Hello i am trying to create a custom module..when i try to install it i get the following error:
Error log:
Error:
Odoo Server Error
Traceback (most recent call last):
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 712, in parse
self._tag_root(de)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 674, in _tag_root
f(rec)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 577, in _tag_record
record = model._load_records([data], self.mode == 'update')
File "/opt/odoo13/odoo/odoo/models.py", line 4163, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/opt/odoo13/odoo/odoo/models.py", line 4077, in _load_records_create
return self.create(values)
File "<decorator-gen-32>", line 2, in create
File "/opt/odoo13/odoo/odoo/api.py", line 336, in _model_create_multi
return create(self, arg)
File "/opt/odoo13/odoo/odoo/addons/base/models/ir_ui_view.py", line 475, in create
return super(View, self).create(vals_list)
File "<decorator-gen-3>", line 2, in create
File "/opt/odoo13/odoo/odoo/api.py", line 336, in _model_create_multi
return create(self, arg)
File "/opt/odoo13/odoo/odoo/models.py", line 3805, in create
records = self._create(data_list)
File "/opt/odoo13/odoo/odoo/models.py", line 3877, in _create
col_val = field.convert_to_column(val, self, stored)
File "/opt/odoo13/odoo/odoo/fields.py", line 2250, in convert_to_column
value = self.convert_to_cache(value, record)
File "/opt/odoo13/odoo/odoo/fields.py", line 2262, in convert_to_cache
raise ValueError("Wrong value for %s: %r" % (self, value))
ValueError: Wrong value for ir.ui.view.type: 'data'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo13/odoo/odoo/http.py", line 624, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/opt/odoo13/odoo/odoo/http.py", line 310, in _handle_exception
raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])
File "/opt/odoo13/odoo/odoo/tools/pycompat.py", line 14, in reraise
raise value
File "/opt/odoo13/odoo/odoo/http.py", line 669, in dispatch
result = self._call_function(**self.params)
File "/opt/odoo13/odoo/odoo/http.py", line 350, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/opt/odoo13/odoo/odoo/service/model.py", line 94, in wrapper
return f(dbname, *args, **kwargs)
File "/opt/odoo13/odoo/odoo/http.py", line 339, in checked_call
result = self.endpoint(*a, **kw)
File "/opt/odoo13/odoo/odoo/http.py", line 915, in __call__
return self.method(*args, **kw)
File "/opt/odoo13/odoo/odoo/http.py", line 515, in response_wrap
response = f(*args, **kw)
File "/opt/odoo13/odoo/addons/web/controllers/main.py", line 1331, in call_button
action = self._call_kw(model, method, args, kwargs)
File "/opt/odoo13/odoo/addons/web/controllers/main.py", line 1319, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/opt/odoo13/odoo/odoo/api.py", line 387, in call_kw
result = _call_kw_multi(method, model, args, kwargs)
File "/opt/odoo13/odoo/odoo/api.py", line 374, in _call_kw_multi
result = method(recs, *args, **kwargs)
File "<decorator-gen-60>", line 2, in button_immediate_install
File "/opt/odoo13/odoo/odoo/addons/base/models/ir_module.py", line 72, in check_and_log
return method(self, *args, **kwargs)
File "/opt/odoo13/odoo/odoo/addons/base/models/ir_module.py", line 463, in button_immediate_install
return self._button_immediate_function(type(self).button_install)
File "/opt/odoo13/odoo/odoo/addons/base/models/ir_module.py", line 573, in _button_immediate_function
modules.registry.Registry.new(self._cr.dbname, update_module=True)
File "/opt/odoo13/odoo/odoo/modules/registry.py", line 86, in new
odoo.modules.load_modules(registry._db, force_demo, status, update_module)
File "/opt/odoo13/odoo/odoo/modules/loading.py", line 423, in load_modules
loaded_modules, update_module, models_to_check)
File "/opt/odoo13/odoo/odoo/modules/loading.py", line 315, in load_marked_modules
perform_checks=perform_checks, models_to_check=models_to_check
File "/opt/odoo13/odoo/odoo/modules/loading.py", line 225, in load_module_graph
load_data(cr, idref, mode, kind='data', package=package, report=report)
File "/opt/odoo13/odoo/odoo/modules/loading.py", line 68, in load_data
tools.convert_file(cr, package.name, filename, idref, mode, noupdate, kind, report)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 736, in convert_file
convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 803, in convert_xml_import
obj.parse(doc.getroot())
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 721, in parse
exc_info[2]
File "/opt/odoo13/odoo/odoo/tools/pycompat.py", line 13, in reraise
raise value.with_traceback(tb)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 712, in parse
self._tag_root(de)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 674, in _tag_root
f(rec)
File "/opt/odoo13/odoo/odoo/tools/convert.py", line 577, in _tag_record
record = model._load_records([data], self.mode == 'update')
File "/opt/odoo13/odoo/odoo/models.py", line 4163, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/opt/odoo13/odoo/odoo/models.py", line 4077, in _load_records_create
return self.create(values)
File "<decorator-gen-32>", line 2, in create
File "/opt/odoo13/odoo/odoo/api.py", line 336, in _model_create_multi
return create(self, arg)
File "/opt/odoo13/odoo/odoo/addons/base/models/ir_ui_view.py", line 475, in create
return super(View, self).create(vals_list)
File "<decorator-gen-3>", line 2, in create
File "/opt/odoo13/odoo/odoo/api.py", line 336, in _model_create_multi
return create(self, arg)
File "/opt/odoo13/odoo/odoo/models.py", line 3805, in create
records = self._create(data_list)
File "/opt/odoo13/odoo/odoo/models.py", line 3877, in _create
col_val = field.convert_to_column(val, self, stored)
File "/opt/odoo13/odoo/odoo/fields.py", line 2250, in convert_to_column
value = self.convert_to_cache(value, record)
File "/opt/odoo13/odoo/odoo/fields.py", line 2262, in convert_to_cache
raise ValueError("Wrong value for %s: %r" % (self, value))
odoo.tools.convert.ParseError: "Wrong value for ir.ui.view.type: 'data'" while parsing /opt/odoo13/odoo/odoo-custom-addons/candidate/views/views.xml:2, near
<odoo>
<!-- Candidate form view-->
<record model="ir.ui.view" id="course_form_view">
<field name="name">candidate form</field>
<field name="model">candidate.application</field>
<field name="arch" type="xml">
<form string="Application Form">
<header>
<button string="Create Employee" name="create_employee_from_applicant" type="object" class="oe_highlight" attrs="{'invisible': ['|',('emp_id', '!=', False),('active', '=', False)]}" confirm="Are you sure?"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_get_attachment_tree_view" icon="fa-file-text-o">
<field name="document_count" widget="statinfo" string="Documents"/>
</button>
</div>
<field name="active" invisible="1"/>
<div>
<h2>
<group string="General Details">
<field name="subject"/>
</group>
</h2>
<h3>
<group><field name="partner_name"/></group>
</h3>
</div>
<group>
<group>
<field name="email"/>
<field name="phone"/>
<field name="mobile"/>
</group>
<group>
<field name="source"/>
<field name="certification"/>
</group>
</group>
<group>
<group string="Job">
<field name="applied_job"/>
<field name="department"/>
</group>
<group string="Contract">
<field name="current_salary"/>
<field name="expected_salary"/>
<field name="availibility"/>
<field name="emp_id" invisible="1"/>
</group>
</group>
<h6>Application Summary</h6>
<field name="summary"/>
<p/>
<field name="partner_id" invisible="1"/>
<div class="oe_highlight"><h6>Profile Summary</h6></div>
<field name="profile_summary"/>
<br/>
<group string="Skills">
<group>
<field name="skills"/>
</group>
</group>
<h6>Skills Summary</h6>
<field name="skills_summary"/>
<group string="Education Details"/>
<field name="educational_details">
<tree>
<field name="degree"/>
<field name="major"/>
<field name="start_date"/>
<field name="end_date"/>
</tree>
<form string="Education Details">
<group>
<field name="degree"/>
<field name="major"/>
<field name="start_date"/>
<field name="end_date"/>
</group>
</form>
</field>
<group string="Employee Details"/>
<field name="employee_details">
<tree>
<field name="current_employer"/>
<field name="total_experience"/>
<field name="emp_start_date"/>
<field name="emp_end_date"/>
<field name="work_title"/>
</tree>
<form string="Employee Details">
<group>
<field name="current_employer"/>
<field name="total_experience"/>
<field name="emp_start_date"/>
<field name="emp_end_date"/>
<field name="work_title"/>
</group>
</form>
</field>
<h6>Experience Summary</h6>
<field name="experience_summary"/>
<p/>
<h6>Employment Description</h6>
<field name="employment_description"/>
<field name="company_id" invisible="1"/>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread" options="{'post_refresh': 'recipients', 'open_attachments': True}"/>
</div>
</form>
</field>
</record>
<!-- candidate tree view-->
<record id="candidate_list_action" model="ir.ui.view">
<field name="name">candidate list</field>
<field name="model">candidate.application</field>
<field name="arch" type="xml">
<tree>
<field name="partner_name"/>
</tree>
</field>
</record>
<!--candidate skills tree, form view -->
<record id="skills_action" model="ir.ui.view">
<field name="name">candidate_skills_view</field>
<field name="model">candidate.skills</field>
<field name="arch" type="xml">
<data><tree string="Skills" editable="bottom">
<field name="skills"/>
</tree>
<form string="Skills">
<field name="skills"/>
</form>
</data></field>
</record>
<!-- candidate 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="candidate_list_action">
<field name="name">Candidate</field>
<field name="res_model">candidate.application</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">Create first Candidate
</p>
</field>
</record>
<!-- candidate skills action window view-->
<record id="skills_action" model="ir.actions.act_window">
<field name="name">Candidate Skills</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">candidate.skills</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Add a skill
</p>
</field>
</record>
<!-- top level menu: no parent -->
<menuitem id="main_openacademy_menu" name="Candidate" action="candidate_list_action"/>
<!-- A first level in the left side menu is needed
before using action= attribute -->
<menuitem id="openacademy_menu" name="Candidate" parent="main_openacademy_menu"/>
<!-- the following menuitem should appear *after*
its parent candidate_menu and *after* its
action course_list_action -->
<!-- Full id location:
action="openacademy.course_list_action"
It is not required when it is the same module -->
<menuitem id="skills" name="Skills" parent="openacademy_menu" action="skills_action"/>
</odoo>
models.py:
from odoo import api, fields, models, SUPERUSER_ID
from odoo.tools.translate import _
from odoo.exceptions import UserError
class Course(models.Model):
_name = 'candidate.application'
_description = "Candidate form"
_inherit = ['mail.thread.cc', 'mail.activity.mixin', 'utm.mixin']
def _default_company_id(self):
company_id = False
if self._context.get('default_department_id'):
department = self.env['hr.department'].browse(self._context['default_department_id'])
company_id = department.company_id.id
if not company_id and self.job_id:
company_id = self.env['hr.job'].browse(self._context['default_job_id']).company_id.ids
if not company_id:
company_id = self.env.company
return company_id
subject = fields.Text(string="Subject")
partner_name = fields.Char(string="Candidate name")
email = fields.Char(string="Email")
phone = fields.Char(string="Phone")
mobile = fields.Char(string="Mobile")
degree = fields.Char(string="Degree")
source = fields.Char(string="Source")
applied_job = fields.Char(string="Applied Job")
department = fields.Char(string="Department")
expected_salary = fields.Char(string="Expected Salary")
proposed_salary = fields.Char(string="Proposed Salary")
availibility = fields.Char(string="Availibility")
summary = fields.Text()
major = fields.Char(string="Major")
start_date = fields.Date(string="Start Date")
end_date = fields.Date(string="End Date")
"""candidate Fields"""
current_salary = fields.Char(string="Current Salary")
resume = fields.Binary()
profile_summary = fields.Text()
skills_summary = fields.Text(string="Skills Summary")
skills = fields.Many2many('candidate.skills', string="Skills")
experience_summary = fields.Text(string="Experience Summary")
employment_description = fields.Text(string="Employment Description")
certification = fields.Char(string="Certification Name")
source = fields.Char(string="Source")
total_experience = fields.Char(string="Total Experience")
current_employer = fields.Char(string="Current Employer")
emp_start_date = fields.Date(string="Employee start Date")
emp_end_date = fields.Date(string="Employee End Date")
work_title = fields.Char(string="Current Work Title")
partner_id = fields.Many2one('res.partner', "Contact", copy=False)
educational_details = fields.One2many('candidate.education', 'educational_ref', 'Educational Details')
employee_details = fields.One2many('candidate.employee', 'employee_ref', 'Employee Details')
document_count = fields.Integer(compute='compute_document_count')
active = fields.Boolean("Active", default=True,
help="If the active field is set to false, it will allow you to hide the case without removing it.")
emp_id = fields.Many2one('hr.employee', string="Employee", help="Employee linked to the applicant.", copy=False)
job_id = fields.Many2one('hr.job', "Job ID")
department_id = fields.Many2one('hr.department', "Department",
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
company_id = fields.Many2one('res.company', "Company", default=_default_company_id)
_sql_constraints = [
('unique_email', 'UNIQUE(email)', 'Candidate with Email address already exists!')
]
def compute_document_count(self):
for record in self:
record.document_count = self.env['candidate.document'].search_count([])
def action_get_attachment_tree_view(self):
action_values = {
'name': _('Documents'),
'domain': [],
'res_model': 'candidate.document',
'view_id': False,
'view_mode': 'kanban,tree,form',
'type': 'ir.actions.act_window',
}
return action_values
def create_employee_from_applicant(self):
""" Create an hr.employee from the hr.applicants """
employee = False
for applicant in self:
contact_name = False
if applicant.partner_id:
address_id = applicant.partner_id.address_get(['contact'])['contact']
contact_name = applicant.partner_id.display_name
else:
if not applicant.partner_name:
raise UserError(_('You must define a Contact Name for this applicant.'))
new_partner_id = self.env['res.partner'].create({
'is_company': False,
'type': 'private',
'name': applicant.partner_name,
'email': applicant.email,
'phone': applicant.phone,
'mobile': applicant.mobile
})
address_id = new_partner_id.address_get(['contact'])['contact']
if applicant.partner_name or contact_name:
employee = self.env['hr.employee'].create({
'name': applicant.partner_name or contact_name,
'job_id': applicant.job_id.id or False,
'job_title': applicant.job_id.name,
'address_home_id': address_id,
'department_id': applicant.department_id.id or False,
'address_id': applicant.company_id and applicant.company_id.partner_id
and applicant.company_id.partner_id.id or False,
'work_email': applicant.department_id and applicant.department_id.company_id
and applicant.department_id.company_id.email or False,
'work_phone': applicant.department_id and applicant.department_id.company_id
and applicant.department_id.company_id.phone or False})
applicant.write({'emp_id': employee.id})
if applicant.job_id:
applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1})
applicant.job_id.message_post(
body=_(
'New Employee %s Hired') % applicant.partner_name if applicant.partner_name else applicant.name,
subtype="hr_recruitment.mt_job_applicant_hired")
applicant.message_post_with_view(
'hr_recruitment.applicant_hired_template',
values={'applicant': applicant},
subtype_id=self.env.ref("hr_recruitment.mt_applicant_hired").id)
employee_action = self.env.ref('hr.open_view_employee_list')
dict_act_window = employee_action.read([])[0]
dict_act_window['context'] = {'form_view_initial_mode': 'edit'}
dict_act_window['res_id'] = employee.id
return dict_act_window
class Skills(models.Model):
_name = 'candidate.skills'
_description = 'Candidate Skills'
_sql_constraints = [
('name_uniq', 'unique (skills)', 'The name of the Degree of Recruitment must be unique!')
]
skills = fields.Char(string="Skills", required=True, translate=True)
class EducationDetails(models.Model):
_name = 'candidate.education'
_description = 'Candidate Education Details'
degree = fields.Char(string="degree")
major = fields.Char(string="Major")
start_date = fields.Date(string="Start Date")
end_date = fields.Date(string="End Date")
educational_ref = fields.Many2one('candidate.application', 'Educational Ref')
class EmployeeDetails(models.Model):
_name = 'candidate.employee'
_description = 'Candidate Employee Details'
total_experience = fields.Char(string="Total Experience")
current_employer = fields.Char(string="Current Employer")
emp_start_date = fields.Date(string="Employee start Date")
emp_end_date = fields.Date(string="Employee End Date")
work_title = fields.Char(string="Current Work Title")
employee_ref = fields.Many2one('candidate.application', 'Employee Ref')
Where am i going wrong?