346 lines
15 KiB
Python
346 lines
15 KiB
Python
# -*- coding:utf-8 -*-
|
|
|
|
from odoo import models, fields, api
|
|
from odoo.tools.translate import _
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class HrTicketing(models.Model):
|
|
_name = 'hr.ticket.request'
|
|
_rec_name = 'employee_id'
|
|
_description = 'Ticket Request'
|
|
_inherit = ['mail.thread']
|
|
|
|
STATE_SELECTION = [
|
|
('draft', _('Draft')),
|
|
('submit', _('Direct Manager')),
|
|
('review', _('Government Relations')),
|
|
('confirm', _('HR Manager')),
|
|
('done', _('Financial Manager')),
|
|
('refuse', _('Refused')),
|
|
# ('cancelled', _('Cancelled')),
|
|
]
|
|
|
|
from_hr = fields.Boolean(_('Another Employee'))
|
|
estimated_ticket_amount = fields.Float(_('Estimated Cost of Ticket'), )
|
|
contract_type = fields.Selection([('single', 'Single'),
|
|
('marriage', 'Married'),
|
|
], string='Contract Type', )
|
|
contract_start_date = fields.Date(string='Contract Start Date', related='employee_id.contract_id.date_start',
|
|
readonly=True)
|
|
contract_end_date = fields.Date(string='Contract End Date', related='employee_id.contract_id.date_end',
|
|
readonly=True)
|
|
contract_duration = fields.Selection(related='employee_id.contract_id.contract_duration', readonly=True)
|
|
|
|
ticket_degree = fields.Selection([
|
|
('first', 'First'),
|
|
('first_reduced', 'First reduced'),
|
|
('economic', 'Economic'),
|
|
('business', 'Business'),
|
|
('other', 'Other'),
|
|
], string='Tickets Degree')
|
|
|
|
request_for = fields.Selection(
|
|
[('employee', 'For Employee Only'), ('family', 'For Family Only'), ('all', 'For Employee and Family'), ],
|
|
_('Request For'))
|
|
note = fields.Text(string='Notes')
|
|
state = fields.Selection(STATE_SELECTION, string='Status', default='draft', tracking=True)
|
|
leave_ticket = fields.Boolean(string='Leave Ticket')
|
|
passport_issue_place = fields.Char(related='employee_id.place_issuance_passport', string='Passport Issue Place')
|
|
passport_issue_date = fields.Date(related='employee_id.date_issuance_passport', string='Passport Issue Date')
|
|
passport_expiry_date = fields.Date(related='employee_id.expiration_date_passport', string="Passport Expiry Date")
|
|
position_type = fields.Selection([
|
|
('Consultant_director', 'Managerial'),
|
|
('normal', 'Normal Job')
|
|
], string='Position Type')
|
|
request_date = fields.Date(string='Request Date', default=fields.Date.today)
|
|
cost_of_tickets = fields.Float(string='Cost Of Tickets')
|
|
|
|
# Relational fields
|
|
employee_id = fields.Many2one('hr.employee', string='Employee', default=lambda self: self._employee_get())
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
|
|
travel_agent = fields.Many2one('airline.agent', string='Travel Agent')
|
|
journal_id = fields.Many2one('account.journal', _('Journal'))
|
|
validators_user_ids = fields.Many2many('res.users', string='Validators')
|
|
# passport_no = fields.Many2one('hr.employee.dependent', string='Passport No.', readonly=True)
|
|
passport_no = fields.Many2one(related='employee_id.passport_id')
|
|
request_type = fields.Many2one('hr.ticket.request.type')
|
|
ticket_check = fields.Boolean(related='request_type.ticket_check')
|
|
air_line = fields.Many2one('hr.airline', string='AirLine')
|
|
attach_ids = fields.One2many('ir.attachment', 'ticket_request_id', string='Attachment')
|
|
|
|
job_id = fields.Many2one('hr.job', string='Job Title', related='employee_id.job_id', readonly=True)
|
|
department_id = fields.Many2one('hr.department', string='Department', related='employee_id.department_id',
|
|
readonly=True)
|
|
nationality_id = fields.Many2one('res.country', string='Nationality', related='employee_id.country_id',
|
|
readonly=True)
|
|
employee_dependant = fields.One2many('hr.employee.dependent', 'contract_id', readonly=True,
|
|
related='employee_id.contract_id.employee_dependant')
|
|
move_id = fields.Many2one('account.move')
|
|
mission_check = fields.Boolean()
|
|
ticket_date = fields.Date(string='Ticket Date')
|
|
destination = fields.Many2one('mission.destination', string='Destination')
|
|
|
|
def unlink(self):
|
|
for item in self:
|
|
if item.state != 'draft':
|
|
raise UserError(_('You can not delete record in state not in draft'))
|
|
return super(HrTicketing, self).unlink()
|
|
|
|
def submit(self):
|
|
#if self.employee_id and self.request_for:
|
|
#if self.employee_id.marital == 'single' and self.request_for in ['family', 'all']:
|
|
# raise ValidationError(_('You are single, can not request ticket for family'))
|
|
self.write({'state': 'submit'})
|
|
|
|
def review(self):
|
|
self.write({'state': 'review'})
|
|
|
|
def confirm(self):
|
|
self.write({'state': 'confirm'})
|
|
|
|
def action_done(self):
|
|
if self.cost_of_tickets > 0:
|
|
debit_line_vals = {
|
|
'name': 'debit',
|
|
'debit': self.cost_of_tickets,
|
|
'date': self.request_date,
|
|
'account_id': self.request_type.account_debit_id.id,
|
|
'partner_id': self.employee_id.user_id.partner_id.id,
|
|
'analytic_account_id': self.request_type.analytic_account_id.id,
|
|
}
|
|
credit_line_vals = {
|
|
'name': 'credit',
|
|
'credit': self.cost_of_tickets,
|
|
'date': self.request_date,
|
|
'account_id': self.journal_id.default_account_id.id,
|
|
'partner_id': self.employee_id.user_id.partner_id.id
|
|
}
|
|
if not self.move_id :
|
|
move_id = self.env['account.move'].create({
|
|
'state': 'draft',
|
|
'journal_id': self.journal_id.id,
|
|
'date': self.request_date,
|
|
'ref': 'Ticket Request for %s' % self.employee_id.name,
|
|
'line_ids': [(0, 0, debit_line_vals), (0, 0, credit_line_vals)],
|
|
'res_model': 'hr.ticket.request',
|
|
'res_id': self.id
|
|
})
|
|
|
|
self.write({
|
|
'state': 'done',
|
|
'move_id': move_id.id
|
|
})
|
|
else:
|
|
self.write({'state': 'done'})
|
|
|
|
def refuse(self):
|
|
self.write({'state': 'refuse'})
|
|
|
|
#
|
|
# def cancel(self):
|
|
# self.write({'state': 'cancelled'})
|
|
|
|
def re_draft(self):
|
|
# when redraft cancel the created account move
|
|
if self.move_id:
|
|
if self.move_id.state == 'draft':
|
|
# self.move_id.write({'state': 'canceled'})
|
|
self.move_id.unlink()
|
|
self.write({
|
|
'state': 'draft',
|
|
'move_id': False
|
|
})
|
|
else:
|
|
raise UserError(
|
|
_('You can not cancel account move "%s" in state not draft') % self.move_id.name)
|
|
else:
|
|
self.state = 'draft'
|
|
|
|
@api.model
|
|
def _employee_get(self):
|
|
employees = self.env['hr.employee'].search([('user_id', '=', self._uid)])
|
|
if len(employees) <= 0:
|
|
raise ValidationError(_('Set This User For Employee Profile'))
|
|
else:
|
|
# if employees[0].contract_id and employees[0].contract_id.emp_type and employees[
|
|
# 0].contract_id.emp_type == 'saudi':
|
|
# raise ValidationError(_('Not allowed to request tickets for the Saudis Employees'))
|
|
return employees[0]
|
|
|
|
@api.constrains('request_for')
|
|
def check_request(self):
|
|
if self.employee_id and self.request_for:
|
|
if self.employee_id.marital == 'single' and self.request_for in ['family', 'all']:
|
|
raise ValidationError(_('You are single, can not request ticket for family'))
|
|
|
|
# Calculate salary rule on change leave type and save it in cost_of_tickets
|
|
@api.onchange('request_type', 'employee_id', 'destination')
|
|
def calculate_cost_of_tickets(self):
|
|
for item in self:
|
|
item.cost_of_tickets = 0.0
|
|
if item.request_type:
|
|
if item.request_type.allowance_name:
|
|
if item.employee_id:
|
|
if item.employee_id.contract_id:
|
|
item.cost_of_tickets = item.compute_rule(item.request_type.allowance_name,
|
|
item.employee_id.contract_id)
|
|
else:
|
|
raise UserError(_('Employee "%s" has no contract') % item.employee_id.name)
|
|
|
|
else:
|
|
if item.destination and item.employee_id:
|
|
if item.employee_id.contract_id:
|
|
employee_class = item.employee_id.contract_id.ticket_class_id
|
|
if employee_class:
|
|
for line in item.destination.class_ids:
|
|
if employee_class == line.ticket_class_id:
|
|
item.cost_of_tickets = line.price
|
|
else:
|
|
raise UserError(_('Employee "%s" has no contract') % item.employee_id.name)
|
|
|
|
# Compute salary rules
|
|
|
|
def compute_rule(self, rule, contract):
|
|
localdict = dict(employee=contract.employee_id, contract=contract)
|
|
|
|
if rule.amount_select == 'percentage':
|
|
total_percent = 0
|
|
if rule.related_benefits_discounts:
|
|
for line in rule.related_benefits_discounts:
|
|
if line.amount_select == 'fix':
|
|
total_percent += self.compute_rule(line, contract)
|
|
elif line.amount_select == 'percentage':
|
|
total_percent += self.compute_rule(line, contract)
|
|
else:
|
|
total_percent += self.compute_rule(line, contract)
|
|
if total_percent:
|
|
if rule.salary_type == 'fixed':
|
|
try:
|
|
return float(total_percent * rule.amount_percentage / 100)
|
|
except:
|
|
raise UserError(
|
|
_('Wrong percentage base or quantity defined for salary rule %s (%s).') % (
|
|
rule.name, rule.code))
|
|
elif rule.salary_type == 'related_levels':
|
|
levels_ids = rule.salary_amount_ids.filtered(
|
|
lambda item: item.salary_scale_level.id == contract.salary_level.id)
|
|
if levels_ids:
|
|
for l in levels_ids:
|
|
try:
|
|
return float(l.salary * total_percent / 100)
|
|
except:
|
|
raise UserError(
|
|
_('Wrong quantity defined for salary rule %s (%s).') % (
|
|
rule.name, rule.code))
|
|
else:
|
|
return 0
|
|
elif rule.salary_type == 'related_groups':
|
|
groups_ids = rule.salary_amount_ids.filtered(
|
|
lambda item: item.salary_scale_group.id == contract.salary_group.id)
|
|
if groups_ids:
|
|
for g in groups_ids:
|
|
try:
|
|
return float(g.salary * total_percent / 100)
|
|
except:
|
|
raise UserError(
|
|
_('Wrong quantity defined for salary rule %s (%s).') % (
|
|
rule.name, rule.code))
|
|
else:
|
|
return 0
|
|
elif rule.salary_type == 'related_degrees':
|
|
degrees_ids = rule.salary_amount_ids.filtered(
|
|
lambda item: item.salary_scale_degree.id == contract.salary_degree.id)
|
|
if degrees_ids:
|
|
for d in degrees_ids:
|
|
try:
|
|
return float(d.salary * total_percent / 100)
|
|
except:
|
|
raise UserError(
|
|
_('Wrong quantity defined for salary rule %s (%s).') % (
|
|
rule.name, rule.code))
|
|
else:
|
|
return 0
|
|
else:
|
|
try:
|
|
return 0
|
|
except:
|
|
raise UserError(_('There is no total for rule : %s') % (rule.name))
|
|
|
|
elif rule.amount_select == 'fix':
|
|
return rule._compute_rule(localdict)[0]
|
|
|
|
else:
|
|
return rule._compute_rule(localdict)[0]
|
|
|
|
|
|
class Attachment(models.Model):
|
|
_inherit = 'ir.attachment'
|
|
|
|
# Relational fields
|
|
ticket_request_id = fields.Many2one(comodel_name='hr.ticket.request')
|
|
|
|
|
|
class hr_airline(models.Model):
|
|
_name = 'hr.airline'
|
|
|
|
name = fields.Char(string='Name')
|
|
ar_name = fields.Char(string='Arabic Name')
|
|
code = fields.Char(string='Code')
|
|
|
|
# Relational fields
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
|
|
|
|
|
|
class hr_airline_city(models.Model):
|
|
_name = 'hr.airline.city'
|
|
|
|
name = fields.Char(string='Name')
|
|
ar_name = fields.Char(string='Arabic Name')
|
|
code = fields.Char(string='Code')
|
|
|
|
# Relational fields
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
|
|
|
|
|
|
class HRTicketDependent(models.Model):
|
|
_inherit = 'hr.ticket.dependent'
|
|
|
|
ticket_request_line = fields.Many2one(comodel_name='hr.ticket.request')
|
|
|
|
|
|
class airline_agent(models.Model):
|
|
_name = 'airline.agent'
|
|
_rec_name = 'agent_name'
|
|
|
|
agent_name = fields.Char(string='Agent Name')
|
|
ar_agent_name = fields.Char(string='Arabic Agent Name')
|
|
account_no = fields.Char(string='Account No.')
|
|
code = fields.Char(string='Code')
|
|
telephone = fields.Char(string='Telephone')
|
|
mobile = fields.Char(string='Mobile')
|
|
fax = fields.Char(string='Fax No.')
|
|
mail = fields.Char(string='E-mail')
|
|
contact_person = fields.Char(string='Contact Person')
|
|
sur_name = fields.Selection([('mr', 'Mr'), ('mrs', 'Mrs'), ('president', 'President')], string='Sur Name')
|
|
# Relational fields
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
|
|
|
|
_sql_constraints = [
|
|
('code_code_unique', 'unique(code)', 'The agency code must be unique per company !'),
|
|
]
|
|
|
|
|
|
class HrTicketingType(models.Model):
|
|
_name = 'hr.ticket.request.type'
|
|
|
|
name = fields.Char()
|
|
ticket_check = fields.Boolean()
|
|
|
|
# relational fields
|
|
allowance_name = fields.Many2one('hr.salary.rule', domain=[('category_id.rule_type', '=', 'allowance')])
|
|
account_debit_id = fields.Many2one('account.account')
|
|
analytic_account_id = fields.Many2one(comodel_name='account.analytic.account',string='Analytic Account')
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
|