Initial commit

This commit is contained in:
Raghupathy K 2024-07-08 13:05:10 +05:30
commit 76e78d47fc
60 changed files with 695 additions and 0 deletions

View File

@ -0,0 +1,39 @@
Manage Recruitment and Job applications
---------------------------------------
Publish, promote and organize your job offers with the Odoo
<a href="https://www.odoo.com/app/recruitment">Open Source Recruitment Application</a>.
Organize your job board, promote your job announces and keep track of
application submissions easily. Follow every applicant and build up a database
of skills and profiles with indexed documents.
Post Your Jobs on Best Job Boards
---------------------------------
Connect automatically to most famous job board websites; linkedIn, Monster,
Craigslist, ... Every job position has a new email address automatically
assigned to route applications automatically to the right job position.
Whether applicants contact you by email or using an online form, you get all
the data indexed automatically (resumes, motivation letter) and you can answer
in just a click, reusing templates of answers.
Customize Your Recruitment Process
----------------------------------
Use the kanban view and customize the steps of your recruitments process;
pre-qualification, first interview, second interview, negociaiton, ...
Get accurate statistics on your recruitment pipeline. Get reports to compare
the performance of your different investments on external job boards.
Streamline Your Recruitment Process
-----------------------------------
Follow applicants in your recruitment process with the smart kanban view. Save
time by automating some communications with email templates.
Documents like resumes and motivation letters are indexed automatically,
allowing you to easily find for specific skills and build up a database of
profiles.

View File

@ -0,0 +1,5 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import wizard

View File

@ -0,0 +1,41 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Recruitment',
'version': '1.1',
'category': 'Human Resources/Recruitment',
'sequence': -100,
'summary': 'Track your recruitment pipeline',
'website': 'https://www.odoo.com/app/recruitment',
'depends': [
'base',
'hr',
'calendar',
'utm',
'attachment_indexation',
'web_tour',
'digest',
],
'data': [
'security/ir.model.access.csv',
# 'data/interview_invite.xml',
'wizard/sendmail_wizard.xml',
'views/hr_applicant_views.xml',
'views/hr_job_views.xml',
],
'demo': [
'data/hr_recruitment_demo.xml',
],
'installable': True,
'application': True,
'assets': {
'web.assets_backend': [
'hr_recruitment/static/src/**/*.js',
'hr_recruitment/static/src/**/*.scss',
'hr_recruitment/static/src/**/*.xml',
'hr_recruitment/static/src/js/tours/hr_recruitment.js',
],
},
'license': 'LGPL-3',
}

Binary file not shown.

View File

@ -0,0 +1,47 @@
<!--<?xml version="1.0"?>-->
<!--<odoo>-->
<!-- <data noupdate="1">-->
<!-- <record id="interview_invitation_meeting" model="mail.template">-->
<!-- <field name="name">Calendar: Interview Meeting Invitation</field>-->
<!-- <field name="model_id" ref="hr_recruitment.model_hr_applicant"/>-->
<!-- <field name="subject">INTERVIEW INVITE | ODIWARE</field>-->
<!-- <field name="email_from">"ODIWARE | HR" &lt;dummymails276@gmail.com&gt;</field>-->
<!-- <field name="email_to">{{ (object.email_from) }}</field>-->
<!-- <field name="partner_to">{{ object.first_interviewer_ids }}</field>-->
<!-- <field name="description">Invitation email to new attendees</field>-->
<!-- <field name="body_html" type="html">-->
<!-- <table style="width: 100%; border-collapse: collapse; border: 1px solid #ccc;">-->
<!-- &lt;!&ndash; Company Logo Row &ndash;&gt;-->
<!-- <tr>-->
<!-- <table style="width: 100%; border-collapse: collapse;">-->
<!-- <td style="width: 80%;padding: 20px;">-->
<!-- </td>-->
<!-- <td style="width: 20%;padding: 20px;">-->
<!-- <img t-attf-src="/logo.png?company={{ user.company_id.id }}"-->
<!-- style="height: auto; width: 80px;" t-att-alt="user.company_id.name"/>-->
<!-- </td>-->
<!-- </table>-->
<!-- </tr>-->
<!-- &lt;!&ndash; Invite Content Greetings Row &ndash;&gt;-->
<!-- <tr>-->
<!-- <td style="padding: 20px;">-->
<!-- <p>Dear<t t-out="object.partner_name"/>,-->
<!-- </p>-->
<!-- <p>We are pleased to invite you for an interview.</p>-->
<!-- </td>-->
<!-- </tr>-->
<!-- &lt;!&ndash; Remaining Content Row &ndash;&gt;-->
<!-- <tr>-->
<!-- <td style="padding: 20px; border-top: 1px solid #ccc;">-->
<!-- <p>Looking forward to meeting you!</p>-->
<!-- <p>Best Regards,</p>-->
<!-- <p>HR Team | ODIWARE</p>-->
<!-- </td>-->
<!-- </tr>-->
<!-- </table>-->
<!-- </field>-->
<!-- </record>-->
<!-- </data>-->
<!--</odoo>-->

View File

@ -0,0 +1,2 @@
from . import hr_applicant
from . import hr_job

View File

@ -0,0 +1,60 @@
from typing import re
from odoo import api, fields, models, _
from datetime import date, datetime, timedelta
from odoo.exceptions import UserError, ValidationError
class HrRecruitment(models.Model):
_inherit = "hr.applicant"
source_ids = fields.Selection([('referral', 'Referral'), ('naukri', 'Naukri'), ('job portal', 'Job Portal')],
string="Source From")
current_city_ids = fields.Char(string="Current City")
preferred_city_ids = fields.Char(string="Preferred City")
current_CTC = fields.Float(string='Current CTC', group_operator="avg", help="Current Salary of the Applicant")
offer_in_hand = fields.Selection([('yes', 'Yes'), ('no', 'No')], string="Offer in Hand")
official_notice_period = fields.Integer(string="Official Notice Period(in days)")
how_soon_can_be_joined = fields.Integer(string="How soon can be joined(in days)")
last_working_day = fields.Date(string="Last Working Day")
current_organization = fields.Text(string="Current Organization")
total_experience = fields.Char(string='Total Experience',
help="Enter the total experience in the format 'X Years Y Months'")
relevant_experience = fields.Char(string="Relevant Experience")
recruiter_name = fields.Many2one("hr.employee", string="Recruiter name")
attachment_ids = fields.One2many('ir.attachment', 'res_id', string="Attachment")
user_id = fields.Many2one('res.users', string='User', default=lambda self: self.env.user.id)
# @api.model
# def create(self, vals):
# res = super(HrRecruitment, self).create(vals)
# res._send_interview_invitation()
# return res
#
# def write(self, vals):
# res = super(HrRecruitment, self).write(vals)
# if 'stage_id' in vals and vals['stage_id']:
# self._send_interview_invitation()
# return res
#
# def _send_interview_invitation(self):
# interview_stage = self.env.ref(
# 'hr_recruitment.hr_recruitment_stage_form')
# for applicant in self:
# if applicant.stage_id == interview_stage:
# template = self.env.ref('hrms_recruitment.interview_invitation_meeting')
# if template:
# template.send_mail(applicant.id, force_send=True)
def action_open_mail_wizard(self):
return {
'name': _('Send Mail'),
'type': 'ir.actions.act_window',
'res_model': 'hr.applicant.mail.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'default_applicant_id': self.id,
},
}

View File

@ -0,0 +1,24 @@
from odoo import api, fields, models, _
from datetime import date, datetime, timedelta
from odoo.exceptions import UserError, ValidationError
class HrRecruitment(models.Model):
_inherit = "hr.job"
account_manager = fields.Many2one("hr.employee", string="Account Manager")
recruiter_name = fields.Many2one("hr.employee", string="Recruiter assignee")
no_of_position = fields.Integer(string="Number of positions")
status = fields.Selection([('in progress', 'In progress'), ('inactive', 'Inactive')],
string="Status")
type_ids = fields.Selection([('fte', 'FTE'), ('tpc', 'TPC')], string="Type")
work_experience = fields.Integer(string="Work Experience(Years)")
skills = fields.Char(string="Skills")
attachment_ids = fields.One2many('ir.attachment', 'res_id', string="Attachment")
rate = fields.Integer(string="Rate", default=0)
city = fields.Char(string="City")
country_id = fields.Many2one('res.country', string="Country")
zip_code = fields.Char(string="Zip Code")
user_id = fields.Many2one('res.users', string='User', default=lambda self: self.env.user.id)

View File

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_applicant_user,hr.applicant.user,model_hr_applicant,base.group_user,1,1,1,1
access_hr_applicant_mail_wizard_user,hr.applicant.mail.wizard.user,model_hr_applicant_mail_wizard,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_applicant_user hr.applicant.user model_hr_applicant base.group_user 1 1 1 1
3 access_hr_applicant_mail_wizard_user hr.applicant.mail.wizard.user model_hr_applicant_mail_wizard base.group_user 1 1 1 1

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg width="50" height="50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><path d="M32 25a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z" fill="#985184"/><path d="M25 46C13.402 46 4 36.598 4 25S13.402 4 25 4s21 9.402 21 21c0 5.799-2.35 11.049-6.15 14.85l-6.365-6.365A11.964 11.964 0 0 0 37 25c0-6.627-5.373-12-12-12s-12 5.373-12 12 5.373 12 12 12v9Z" fill="#1AD3BB"/><path fill-rule="evenodd" clip-rule="evenodd" d="M25 37a11.958 11.958 0 0 1-8.345-3.377A9 9 0 0 0 25 46h13a9 9 0 0 0-9-9h-4Z" fill="#985184"/></svg>

After

Width:  |  Height:  |  Size: 509 B

View File

@ -0,0 +1,36 @@
/** @odoo-module */
import { CharField, charField } from "@web/views/fields/char/char_field";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
export class ApplicantCharField extends CharField {
setup() {
super.setup();
this.action = useService("action");
}
onClick() {
const record = this.props.record.data;
if (record.res_id !== undefined && record.res_model == 'hr.applicant') {
this.action.doAction({
type: 'ir.actions.act_window',
res_model: 'hr.applicant',
res_id: record.res_id,
views: [[false, "form"]],
view_mode: "form",
target: "current",
});
}
}
}
ApplicantCharField.template = "hr_recruitment.ApplicantCharField";
export const applicantCharField = {
...charField,
component: ApplicantCharField,
};
registry.category("fields").add("applicant_char", applicantCharField);

View File

@ -0,0 +1,7 @@
.o_field_applicant_char {
color: $link-color;
&:hover {
color: $link-hover-color;
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="hr_recruitment.ApplicantCharField" t-inherit="web.CharField" t-inherit-mode="primary">
<xpath expr="//span[@t-esc='formattedValue']" position="attributes">
<attribute name="t-on-click.prevent.stop">onClick</attribute>
</xpath>
</t>
</templates>

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,105 @@
/** @odoo-module **/
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { stepUtils } from "@web_tour/tour_service/tour_utils";
import { markup } from "@odoo/owl";
registry.category("web_tour.tours").add('hr_recruitment_tour',{
url: "/web",
rainbowManMessage: () => markup(_t("<div>Great job! You hired a new colleague!</div><div>Try the Website app to publish job offers online.</div>")),
fadeout: 'very_slow',
sequence: 230,
steps: () => [stepUtils.showAppsMenuItem(), {
trigger: '.o_app[data-menu-xmlid="hr_recruitment.menu_hr_recruitment_root"]',
content: markup(_t("Let's have a look at how to <b>improve</b> your <b>hiring process</b>.")),
position: 'right',
edition: 'community'
}, {
trigger: '.o_app[data-menu-xmlid="hr_recruitment.menu_hr_recruitment_root"]',
content: markup(_t("Let's have a look at how to <b>improve</b> your <b>hiring process</b>.")),
position: 'bottom',
edition: 'enterprise'
}, {
trigger: ".o-kanban-button-new",
content: _t("Create your first Job Position."),
position: "bottom",
width: 195
}, {
trigger: ".o_job_name",
extra_trigger: '.o_hr_job_simple_form',
content: _t("What do you want to recruit today? Choose a job title..."),
position: "right"
}, {
trigger: ".o_job_alias",
extra_trigger: '.o_hr_job_simple_form',
content: _t("Choose an application email."),
position: "right",
width: 195
}, {
trigger: '.o_create_job',
content: _t('Let\'s create the position. An email will be setup for applications, and a public job description, if you use the Website app.'),
position: 'bottom',
run: function (actions) {
actions.auto('.modal:visible .btn.btn-primary');
},
}, {
trigger: ".oe_kanban_action_button",
extra_trigger: '.o_hr_recruitment_kanban',
content: _t("Let\'s have a look at the applications pipeline."),
position: "bottom"
}, {
trigger: ".o_copy_paste_email",
content: _t("Copy this email address, to paste it in your email composer, to apply."),
position: "bottom"
}, {
trigger: ".breadcrumb-item:not(.active):last",
extra_trigger: '.o_kanban_applicant',
content: _t("Lets go back to the dashboard."),
position: "bottom",
width: 195
}, {
trigger: ".oe_kanban_action_button",
extra_trigger: '.o_hr_recruitment_kanban',
content: markup(_t("<b>Did you apply by sending an email?</b> Check incoming applications.")),
position: "bottom"
}, {
trigger: ".oe_kanban_card",
extra_trigger: '.o_kanban_applicant',
content: markup(_t("<b>Drag this card</b>, to qualify him for a first interview.")),
position: "bottom",
run: "drag_and_drop .o_kanban_group:eq(1) ",
}, {
trigger: ".oe_kanban_card",
extra_trigger: '.o_kanban_applicant',
content: markup(_t("<b>Click to view</b> the application.")),
position: "bottom",
width: 195
}, {
trigger: "button:contains(Send message)",
extra_trigger: '.o_applicant_form',
content: markup(_t("<div><b>Try to send an email</b> to the applicant.</div><div><i>Tips: All emails sent or received are saved in the history here</i>")),
position: "bottom"
}, {
trigger: ".o-mail-Chatter .o-mail-Composer button[aria-label='Send']",
extra_trigger: '.o_applicant_form',
content: _t("Send your email. Followers will get a copy of the communication."),
position: "bottom"
}, {
trigger: "button:contains(Log note)",
extra_trigger: '.o_applicant_form',
content: _t("Or talk about this applicant privately with your colleagues."),
position: "bottom"
}, {
trigger: ".o_create_employee",
extra_trigger: '.o_applicant_form',
content: _t("Lets create this new employee now."),
position: "bottom",
width: 225
}, {
trigger: ".o_form_button_save",
extra_trigger: ".o_hr_employee_form_view",
content: _t("Save it!"),
position: "bottom",
width: 80
}]});

View File

@ -0,0 +1,22 @@
.o_applicant_interviewer_form {
.o-mail-Chatter-sendMessage,
.o-mail-Chatter-logNote,
.o-mail-Thread-empty {
display: none;
}
}
.o_form_view.o_applicant_form .o_form_renderer {
&.o_form_readonly {
.o_field_empty:empty {
min-height: unset;
}
}
&.o_form_editable {
.oe_title {
max-width: unset;
}
}
}

View File

@ -0,0 +1,43 @@
.o_kanban_dashboard.o_hr_recruitment_kanban {
.o_kanban_renderer {
&.o_kanban_ungrouped .o_kanban_record {
width: 450px;
&:not(.o_kanban_ghost) {
min-height: 220px;
}
}
.text_top_padding{
padding-top: 0.375rem;
}
.o_primary {
display: flex !important;
align-items: center;
justify-content: space-between;
padding-right: 24px !important;
.fa {
margin-left: 0;
}
}
.o_job_activities {
list-style-type: none;
}
.o_kanban_card_header_title {
min-height: 3rem;
.o_field_boolean_favorite {
display: inline;
}
}
}
}
.o_kanban_view {
.o_view_sample_data .ribbon {
display: none;
}
}

View File

@ -0,0 +1,28 @@
/** @odoo-module */
import { registry } from '@web/core/registry';
import { formView } from '@web/views/form/form_view';
import { FormController } from '@web/views/form/form_controller';
export class InterviewerFormController extends FormController {
/**
* Add `o_applicant_interviewer_form` class if necessary
*/
get className() {
const result = super.className;
const root = this.model.root;
if (!root.data.interviewer_ids || !root.data.user_id) {
return result;
}
result["o_applicant_interviewer_form"] = root.data.interviewer_ids.records.findIndex(
interviewer => interviewer.resId === root.data.user_id[0]) > -1;
return result;
}
}
registry.category('views').add('hr_recruitment_interviewer', {
...formView,
Controller: InterviewerFormController,
});

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record model="ir.ui.view" id="hr_applicant_form_view">
<field name="name">hr.applicant.form.view</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type_id']" position="after">
<field name="source_ids"/>
<field name="current_city_ids"/>
<field name="preferred_city_ids"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_applicant_form_view_name">
<field name="name">hr.applicant.form.view</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<!-- <xpath expr="//h1[@class='d-flex justify-content-between align-items-center']" position="attributes">-->
<!-- <attribute name="invisible">1</attribute>-->
<!-- </xpath>-->
<xpath expr="//field[@name='name']" position="attributes">
<attribute name="required">0</attribute>
</xpath>
<xpath expr="//field[@name='partner_name']" position="attributes">
<attribute name="required">1</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_applicant_form_view_recruiter">
<field name="name">hr.applicant.form.view</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='user_id']" position="attributes">
<attribute name="readonly">1</attribute>
</xpath>
</field>
</record>
<record id="hrms_recruitment_current_ctc" model="ir.ui.view">
<field name="name">ld.hr.applicant.current.ctc</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//label[@for='salary_expected']" position="before">
<field name="current_CTC"/>
</xpath>
</field>
</record>
<record id="hrms_recruitment_offer" model="ir.ui.view">
<field name="name">ld.hr.applicant.offer</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='recruitment_contract']" position="after">
<group string="Other INFO">
<field name="offer_in_hand" widget="radio"/>
<field name="official_notice_period"/>
<field name="how_soon_can_be_joined"/>
<field name="last_working_day"/>
<field name="recruiter_name"/>
</group>
<group string="">
<field name="total_experience"/>
<field name="relevant_experience"/>
<field name="current_organization"/>
</group>
</xpath>
</field>
</record>
<record id="hrms_recruitment_attachment" model="ir.ui.view">
<field name="name">ld.hr.applicant.offer</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='categ_ids']" position="after">
<field name="attachment_ids" widget="many2many_binary"/>
</xpath>
</field>
</record>
<record id="hr_applicant_form_view_send_mail" model="ir.ui.view">
<field name="name">hr.applicant.form.view.send.mail</field>
<field name="model">hr.applicant</field>
<field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/>
<field name="arch" type="xml">
<xpath expr="//header" position="inside">
<button name="action_open_mail_wizard" type="object" string="Send Mail" class="btn-primary"/>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record model="ir.ui.view" id="hr_job_form_view">
<field name="name">hr.job.form.view</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[@name='recruitment_page']/group" position="before">
<group string="Official Details">
<field name="account_manager"/>
<field name="recruiter_name"/>
<field name="no_of_position"/>
</group>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_job_form_view_status">
<field name="name">hr.job.form.view</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='department_id']" position="before">
<field name="status"/>
<field name="type_ids" widget="radio"/>
<field name="work_experience"/>
<field name="skills"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_job_form_view_attach">
<field name="name">hr.job.form.view</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='interviewer_ids']" position="after">
<field name="attachment_ids" widget="many2many_binary"/>
<field name="rate" widget="star_rating"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_job_form_view_address">
<field name="name">hr.job.form.view</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='contract_type_id']" position="after">
<field name="city"/>
<field name="country_id"/>
<field name="zip_code"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="hr_job_form_view_recruiter">
<field name="name">hr.job.form.view</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='user_id']" position="attributes">
<attribute name="readonly">1</attribute>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1 @@
from . import sendmail_wizard

View File

@ -0,0 +1,33 @@
from odoo import api, fields, models, _
class HrApplicantMailWizard(models.TransientModel):
_name = 'hr.applicant.mail.wizard'
_description = 'HR Applicant Mail Wizard'
applicant_id = fields.Many2one('hr.applicant', string="Applicant", required=True)
partner_name = fields.Char(related='applicant_id.partner_name', string="Partner Name", store=True, readonly=True)
choose_template = fields.Many2one('mail.template', string="Choose Template",
domain=[('name', 'ilike', 'recruitment')], required=True)
template_body = fields.Html(string="Template Body", related='choose_template.body_html', readonly=False)
def send_mail(self):
self.ensure_one()
template = self.choose_template
if template:
mail_values = {
'subject': template.subject,
'body_html': self.template_body,
'email_to': self.applicant_id.partner_name,
'recipient_ids': [(6, 0, [self.applicant_id.partner_id.id])],
'model': 'hr.applicant',
'res_id': self.applicant_id.id,
'email_from': self.env.user.email,
}
self.env['mail.mail'].create(mail_values).send()
# def send_mail(self):
# self.ensure_one()
# template = self.env.ref('__custom__.hr_recruitment.email_template_First_interview')
# if template:
# template.send_mail(self.applicant_id.id, force_send=True)

View File

@ -0,0 +1,19 @@
<odoo>
<record id="view_hr_applicant_mail_wizard_form" model="ir.ui.view">
<field name="name">hr.applicant.mail.wizard.form</field>
<field name="model">hr.applicant.mail.wizard</field>
<field name="arch" type="xml">
<form string="Send Mail">
<group>
<field name="applicant_id"/>
<field name="choose_template"/>
<field name="template_body"/>
</group>
<footer>
<button string="Send" type="object" name="send_mail" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>