Add odex25_hr

This commit is contained in:
expert 2024-06-24 14:09:02 +03:00
parent 3a3f834c54
commit 0be409eab9
1359 changed files with 465536 additions and 1 deletions

View File

@ -1,2 +1,2 @@
# odex25-standard-moduless
# odex25-standard-modules
This Repo contains general standard modules for all projects.

View File

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

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
{
"name": "Attendance Custom Widget",
"version": "14.0",
"summary": "",
"author": "ronozoro",
"category": "Extra",
'depends': ['base', 'hr_attendance','attendances'],
'data': [
"views/assets.xml",
],
'qweb': [
"static/xml/attendance.xml",
],
"installable": True,
"auto_install": False,
}

View File

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

View File

@ -0,0 +1,86 @@
from typing import Optional, Any, Dict
from odoo import fields, models, api
from odoo.tools.translate import _
class HrEmployeeBase(models.AbstractModel):
_inherit = 'hr.employee.base'
attendance_state = fields.Selection(string="Attendance Status", compute='_compute_attendance_state_new',
selection=[('checked_out', "Checked out"), ('checked_in', "Checked in")])
@api.depends('last_attendance_id.check_in', 'last_attendance_id.check_out', 'last_attendance_id')
def _compute_attendance_state_new(self):
for employee in self:
att = self.env['attendance.attendance'].sudo().search([('employee_id', '=', employee.id)],
limit=1, order='id desc')
if att:
employee.attendance_state = 'checked_in' if att.action == 'sign_in' else 'checked_out'
else:
employee.attendance_state = 'checked_out'
class HrEmployee(models.Model):
_inherit = 'hr.employee'
def attendance_manual(self, next_action: str, entered_pin: Optional[str] = None, **kwargs: Any) -> Dict[str, Any]:
selected_action = kwargs.get('selected_action', 'none')
self.ensure_one()
attendance_user_and_no_pin = self.user_has_groups(
'hr_attendance.group_hr_attendance_user,'
'!hr_attendance.group_hr_attendance_use_pin')
can_check_without_pin = attendance_user_and_no_pin or (self.user_id == self.env.user and entered_pin is None)
if can_check_without_pin or entered_pin is not None and entered_pin == self.sudo().pin:
return self._attendance_action(next_action, selected_action)
return {'warning': _('Wrong PIN')}
def _attendance_action(self, next_action: str, selected_action: Optional[str] = None) -> Dict[str, Any]:
if not selected_action:
return super(HrEmployee, self)._attendance_action(next_action)
self.ensure_one()
employee = self.sudo()
action_message = self.env["ir.actions.actions"]._for_xml_id(
"hr_attendance.hr_attendance_action_greeting_message")
last_attendance_id = self.env['attendance.attendance'].sudo().search([('employee_id', '=', self.id)],
limit=1, order='id desc')
action_message['previous_attendance_change_date'] = last_attendance_id and last_attendance_id.action_date
action_message['employee_name'] = employee.name
action_message['barcode'] = employee.barcode
action_message['next_action'] = next_action
action_message['hours_today'] = employee.hours_today
if employee.user_id:
modified_attendance = employee.with_user(employee.user_id)._attendance_action_change(selected_action)
else:
modified_attendance = employee._attendance_action_change(selected_action)
action_message['attendance'] = modified_attendance.read()[0]
if modified_attendance.action == 'sign_in':
action_message['attendance']['check_in'] = action_message['attendance']['name']
else:
action_message['attendance']['check_out'] = action_message['attendance']['name']
return {'action': action_message}
def _attendance_action_change(self, selected_action: Optional[str] = None) -> "models.Model":
if not selected_action:
return super(HrEmployee, self)._attendance_action_change()
self.ensure_one()
if selected_action in ('sign_out', 'sign_in'):
vals = {
'employee_id': self.id,
'action': selected_action,
'action_type': 'manual'
}
return self.env['attendance.attendance'].create(vals)
attendance = self.env['attendance.attendance'].search([('employee_id', '=', self.id)],
limit=1, order='id desc')
if not attendance:
return self._attendance_action_change(selected_action='sign_in')
vals = {
'employee_id': self.id,
'action': 'sign_in' if attendance.action == 'sign_out' else 'sign_out',
'action_type': 'manual'
}
return self.env['attendance.attendance'].create(vals)

View File

@ -0,0 +1,25 @@
odoo.define('attendance_custom_widget.attendance', function (require) {
var MyAttendance = require('hr_attendance.my_attendances');
MyAttendance.include({
update_attendance: function () {
var self = this;
var selected_action = this.$el.find('.o_sign_in_out_selection').val();
this._rpc({
model: 'hr.employee',
method: 'attendance_manual',
args: [[self.employee.id], 'hr_attendance.hr_attendance_action_my_attendances'],
kwargs: {selected_action: selected_action},
})
.then(function (result) {
console.log(result.action);
if (result.action) {
self.do_action(result.action);
} else if (result.warning) {
self.do_warn(result.warning);
}
});
},
});
return MyAttendance;
});

View File

@ -0,0 +1,26 @@
odoo.define('attendance_custom_widget.kiosk_confirm', function (require) {
var KioskConfirm = require('hr_attendance.kiosk_confirm');
KioskConfirm.include({
events: _.extend({}, KioskConfirm.prototype.events, {
"click .o_hr_attendance_sign_in_out_icon": _.debounce(function () {
var self = this;
var selected_action = this.$el.find('.o_sign_in_out_selection').val();
this._rpc({
model: 'hr.employee',
method: 'attendance_manual',
args: [[this.employee_id], this.next_action],
kwargs: {selected_action: selected_action},
})
.then(function (result) {
if (result.action) {
self.do_action(result.action);
} else if (result.warning) {
self.do_warn(result.warning);
}
});
}, 200, true)
}),
});
return KioskConfirm;
});

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="HrAttendanceMyMainMenu">
<t t-jquery="div[class='o_hr_attendance_kiosk_mode']" t-operation="replace">
<div class="o_hr_attendance_kiosk_mode">
<t t-set="checked_in" t-value="widget.employee.attendance_state=='checked_in'"/>
<t t-if="widget.employee">
<div class="o_hr_attendance_user_badge o_home_menu_background">
<img class="img rounded-circle" t-attf-src="/web/image?model=hr.employee.public&amp;field=image_128&amp;id=#{widget.employee.id}" t-att-title="widget.employee.name" t-att-alt="widget.employee.name"/>
</div>
<h1 class="mb8"><t t-esc="widget.employee.name"/></h1>
<h3 class="mt8 mb24"><t t-if="!checked_in">Welcome!</t><t t-else="">Want to check out?</t></h3>
<h4 class="mt0 mb0 text-muted" t-if="checked_in">Today's work hours: <span t-esc="widget.hours_today"/></h4>
<a class="fa fa-7x o_hr_attendance_sign_in_out_icon fa-sign-out btn-warning" t-if="checked_in" aria-label="Sign out" title="Sign out"/>
<a class="fa fa-7x o_hr_attendance_sign_in_out_icon fa-sign-in btn-secondary" t-if="!checked_in" aria-label="Sign in" title="Sign in"/>
<h3 class="mt0 mb0 text-muted">Click to <b t-if="checked_in">check out</b><b t-if="!checked_in">check in</b></h3>
<select class="o_sign_in_out_selection">
<option value="none">Default</option>
<option value="sign_in">Sign In</option>
<option value="sign_out">Sign Out</option>
</select>
</t>
<t t-else="">
Warning : Your user should be linked to an employee to use attendance. Please contact your administrator.
</t>
</div>
</t>
</t>
<t t-extend="HrAttendanceKioskConfirm">
<t t-jquery="div[class='o_hr_attendance_kiosk_mode']" t-operation="replace">
<div class="o_hr_attendance_kiosk_mode">
<t t-set="checked_in" t-value="widget.employee_state=='checked_in'"/>
<div class="o_hr_attendance_back_button">
<span class="btn btn-secondary btn-lg d-block d-md-none"><i class="fa fa-chevron-left mr8"/> Go back</span>
<span class="btn btn-secondary d-none d-md-inline-block"><i class="fa fa-chevron-left" role="img" aria-label="Go back" title="Go back"/></span>
</div>
<t t-if="widget.employee_id">
<div class="o_hr_attendance_user_badge o_home_menu_background">
<img class="img rounded-circle" t-attf-src="/web/image?model=hr.employee.public&amp;field=image_128&amp;id=#{widget.employee_id}" t-att-title="widget.employee_name" t-att-alt="widget.employee_name"/>
</div>
<h1 class="mb8"><t t-esc="widget.employee_name"/></h1>
<h3 class="mt8 mb24"><t t-if="!checked_in">Welcome!</t><t t-else="">Want to check out?</t></h3>
<h4 class="mt0 mb0 text-muted" t-if="checked_in">Today's work hours: <span t-esc="widget.employee_hours_today"/></h4>
<t t-if="!widget.use_pin">
<a class="fa fa-7x o_hr_attendance_sign_in_out_icon fa-sign-out btn-warning" t-if="checked_in" aria-label="Sign out" title="Sign out"/>
<a class="fa fa-7x o_hr_attendance_sign_in_out_icon fa-sign-in btn-secondary" t-if="!checked_in" aria-label="Sign in" title="Sign in"/>
<h3 class="mt0 mb0 text-muted">Click to <b t-if="checked_in">check out</b><b t-else="">check in</b></h3>
<select class="o_sign_in_out_selection">
<option value="none">Default</option>
<option value="sign_in">Sign In</option>
<option value="sign_out">Sign Out</option>
</select>
</t>
<t t-else="">
<h3 class="mt0 mb0 text-muted">Please enter your PIN to <b t-if="checked_in">check out</b><b t-else="">check in</b></h3>
<div class="row">
<div class="col-md-8 offset-md-2 o_hr_attendance_pin_pad">
<div class="row" >
<div class="col-12 mb8 mt8"><input class="o_hr_attendance_PINbox text-center" type="password" disabled="true"/></div>
</div>
<div class="row">
<t t-foreach="['1', '2', '3', '4', '5', '6', '7', '8', '9', ['C', 'btn-warning'], '0', ['ok', 'btn-primary']]" t-as="btn_name">
<div class="col-4 mb4">
<a t-attf-class="btn {{btn_name[1]? btn_name[1] : 'btn-secondary'}} btn-block btn-lg {{ 'o_hr_attendance_pin_pad_button_' + btn_name[0] }}"><t t-esc="btn_name[0]"/></a>
</div>
</t>
</div>
</div>
</div>
</t>
</t>
<div t-else="" class="alert alert-danger" role="alert">
<b>Error: could not find corresponding employee.</b><br/>Please return to the main menu.
</div>
<a role="button" class="oe_attendance_sign_in_out" aria-label="Sign out" title="Sign out"/>
</div>
</t>
</t>
</templates>

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<odoo>
<template id="attendance_asset_backend" name="attendance assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/attendance_custom_widget/static/js/attendance.js"></script>
<script type="text/javascript" src="/attendance_custom_widget/static/js/kiosk_confirm.js"></script>
</xpath>
</template>
</odoo>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import wizard
from . import report

View File

@ -0,0 +1,31 @@
{
'name': 'HR Attendance customizations',
'category': 'Odex25-HR/Odex25-HR',
'summary': 'HR Management Attendance config module',
'description': """It is a procedure that Record all Employee attendance """,
'version': '1.0',
'sequence': 4,
'website': 'http://exp-sa.com',
'license': 'GPL-3',
'author': 'Expert Co. Ltd.' ,
'depends': ['base', 'hr_attendance', 'report_xlsx','hr_base','exp_payroll_custom'],
'data': [
'security/attendance_security.xml',
'security/ir.model.access.csv',
'data/ir_cron.xml',
'views/hr_attendance_report.xml',
'views/hr_attendance_transactions.xml',
'views/hr_lateness_reasons.xml',
'views/hr_attendance_register_view.xml',
'views/hr_attendance_view.xml',
'wizard/attendance_wizard_view.xml',
'wizard/attendances_report_view.xml',
'views/attendance_menu_item_view.xml',
'views/hr_employee_view.xml',
'report/employee_attendances_report_template.xml',
],
'installable': True,
'application': True,
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="hr_attendance_transaction_create" model="ir.cron">
<field name="name">Attendance Transaction</field>
<field name="model_id" ref="model_hr_attendance_transaction"/>
<field name="state">code</field>
<field name="code">model.process_attendance_scheduler_queue()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
</record>
</odoo>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from . import hr_attendance_report
from . import hr_attendance_report_line
from . import hr_reasons_lateness
from . import hr_attendance_transactions
from . import hr_attendance_register
from . import hr_attendance

View File

@ -0,0 +1,426 @@
# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT
class HrAttendances(models.Model):
_inherit = 'resource.calendar'
def _get_default_attendance_ids(self):
return [
(0, 0, {'name': _('Monday Morning'), 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Monday Evening'), 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Tuesday Morning'), 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Tuesday Evening'), 'dayofweek': '1', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Wednesday Morning'), 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Wednesday Evening'), 'dayofweek': '2', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Thursday Morning'), 'dayofweek': '3', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Thursday Evening'), 'dayofweek': '3', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Friday Morning'), 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Friday Evening'), 'dayofweek': '4', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Saturday Morning'), 'dayofweek': '5', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Saturday Evening'), 'dayofweek': '5', 'hour_from': 13, 'hour_to': 17}),
(0, 0, {'name': _('Sunday Morning'), 'dayofweek': '6', 'hour_from': 8, 'hour_to': 12}),
(0, 0, {'name': _('Sunday Evening'), 'dayofweek': '6', 'hour_from': 13, 'hour_to': 17})
]
name = fields.Char(string='Description')
is_full_day = fields.Boolean(string='Is Full Day ?', default=True)
full_min_sign_in = fields.Float(string='Min Sign In')
full_max_sign_in = fields.Float(string='Max Sign In')
full_min_sign_out = fields.Float(string='Min Sign out')
full_max_sign_out = fields.Float(string='Max Sign out')
full_start_sign_in = fields.Float(string='Start Sign In')
full_end_sign_in = fields.Float(string='End Sign In')
full_start_sign_out = fields.Float(string='Start Sign Out')
full_end_sign_out = fields.Float(string='End Sign Out')
working_hours = fields.Float(string='Working Hours')
working_days = fields.Integer(string='Working Days')
break_duration = fields.Float("Break Duration", default=0.0)
end_sign_in = fields.Float(string='Time to calculate today as absence')
full_day_off = fields.One2many('days.off', 'day_off_attendance')
shift_day_off = fields.One2many('days.off', 'day_off_attendance')
special_days = fields.One2many('attendance.special.days', 'special_days_attendance')
special_days_partcial = fields.One2many('attendance.special.days', 'special_days_attendance')
deduction_rule = fields.Many2one('hr.salary.rule', string='Deduction Rule')
active = fields.Boolean(string='Active', default=True)
employee_ids = fields.One2many('hr.employee', 'resource_calendar_id', string='Employees',
domain=[('state', '=', 'open')])
# Flexible Days
is_flexible = fields.Boolean(string='Is Flexible?')
number_of_flexi_days = fields.Integer(string='Flexible Days')
total_flexible_hours = fields.Float(string='Total Hours For Flexible Days', compute='compute_flexible_hours')
noke = fields.Boolean(string='NOC')
# shift one
shift_one_min_sign_in = fields.Float(string='Min Sign In')
shift_one_max_sign_in = fields.Float(string='Max Sign In')
shift_one_min_sign_out = fields.Float(string='Min Sign out')
shift_one_max_sign_out = fields.Float(string='Max Sign out')
shift_one_start_sign_in = fields.Float(string='Start Sign In')
shift_one_end_sign_in = fields.Float(string='End Sign In')
shift_one_start_sign_out = fields.Float(string='Start Sign Out')
shift_one_end_sign_out = fields.Float(string='End Sign Out')
shift_one_working_hours = fields.Float(string='Working Hours')
shift_one_break_duration = fields.Float("Break Duration", default=0.0)
# shift two
shift_two_min_sign_in = fields.Float(string='Min Sign In')
shift_two_max_sign_in = fields.Float(string='Max Sign In')
shift_two_min_sign_out = fields.Float(string='Min Sign out')
shift_two_max_sign_out = fields.Float(string='Max Sign out')
shift_two_start_sign_in = fields.Float(string='Start Sign In')
shift_two_end_sign_in = fields.Float(string='End Sign In')
shift_two_start_sign_out = fields.Float(string='Start Sign Out')
shift_two_end_sign_out = fields.Float(string='End Sign Out')
shift_two_working_hours = fields.Float(string='Working Hours')
state = fields.Selection([('draft', _('Draft')),
('confirm', _('Confirmed')),
('update', _('Updated'))], string='State', default="draft")
parent_calendar_id = fields.Many2one('resource.calendar', string='Parent Calender')
shift_two_break_duration = fields.Float("Break Duration", default=0.0)
attendance_ids = fields.One2many(
'resource.calendar.attendance', 'calendar_id', 'Working Time',
copy=True, default=_get_default_attendance_ids)
@api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
if args is None: args = []
args.append(('state', '=', 'confirm'))
return super(HrAttendances, self).name_search(name, args=args, operator=operator, limit=limit)
def compute_flexible_hours(self):
for item in self:
item.total_flexible_hours = 0
two_shift = item.shift_one_working_hours + item.shift_two_working_hours
if item.is_flexible is True:
if item.is_full_day:
item.total_flexible_hours = item.working_hours * item.number_of_flexi_days
else:
item.total_flexible_hours = two_shift * item.number_of_flexi_days
# Constraints for Working hours in two cases (Full or Part Time)
@api.constrains('working_hours', 'shift_one_working_hours', 'shift_two_working_hours', 'special_days')
def result_greed_constrains(self):
for item in self:
if item.is_full_day:
hours = item.full_min_sign_out - item.full_min_sign_in
work_hours = item.working_hours
if work_hours != hours:
raise ValidationError(_('Working Hours must be equal to "%s"') % hours)
if item.special_days:
for line in item.special_days:
if not item.is_full_day:
hours = line.start_sign_in - line.start_sign_out
else:
hours = line.start_sign_out - line.start_sign_in
if line.working_hours != hours:
raise ValidationError(_('Working Hours for special days must be equal to "%s"') % hours)
else:
shift_one = self.get_shift_working_hour(self.shift_one_min_sign_in, self.shift_one_min_sign_out)
shift_two = self.get_shift_working_hour(self.shift_two_min_sign_in, self.shift_two_min_sign_out)
if item.shift_one_working_hours != shift_one:
raise ValidationError(
_('Edit Shift(One) Min sign in and min sign out to match working hours "%s"') % shift_one)
if item.shift_two_working_hours > shift_two:
raise ValidationError(
_('edit Shift(Two) Min sign in and min sign out to match working hours "%s"') % shift_two)
def calendar_special_days_change(self):
parent_spds = self. is_full_day and \
self.parent_calendar_id.special_days or self.parent_calendar_id.special_days_partcial
special_days = self. is_full_day and self.special_days or self.special_days_partcial
amended = False
sp_day_list = parent_spds.mapped('name')
for spd in special_days:
if spd.name not in sp_day_list:
amended = True
break
parent_spd = parent_spds.filtered(lambda day: day.name == spd.name)
if spd.start_sign_in != parent_spd.start_sign_in\
or spd.end_sign_in != parent_spd.end_sign_in\
or spd.start_sign_out != parent_spd.start_sign_out\
or spd.end_sign_out != parent_spd.end_sign_out\
or spd.working_hours != parent_spd.working_hours\
or spd.date_from and not parent_spd.date_from\
or not spd.date_from and parent_spd.date_from\
or spd.date_from and parent_spd.date_from and spd.date_from != parent_spd.date_from\
or spd.date_to and not parent_spd.date_to\
or not spd.date_to and parent_spd.date_to\
or spd.date_to and parent_spd.date_to and spd.date_to != parent_spd.date_to:
amended = True
break
return amended
def act_confirm(self):
if not self.parent_calendar_id: self.state = 'confirm'
else:
if self.is_full_day != self.parent_calendar_id.is_full_day \
or self.full_min_sign_in != self.parent_calendar_id.full_min_sign_in \
or self.full_max_sign_in != self.parent_calendar_id.full_max_sign_in \
or self.full_min_sign_out != self.parent_calendar_id.full_min_sign_out \
or self.full_max_sign_out != self.parent_calendar_id.full_max_sign_out \
or self.working_hours != self.parent_calendar_id.working_hours \
or self.working_days != self.parent_calendar_id.working_days \
or self.break_duration != self.parent_calendar_id.break_duration \
or self.end_sign_in != self.parent_calendar_id.end_sign_in \
or self.is_flexible != self.parent_calendar_id.is_flexible \
or self.number_of_flexi_days != self.parent_calendar_id.number_of_flexi_days \
or self.total_flexible_hours != self.parent_calendar_id.total_flexible_hours \
or self.noke != self.parent_calendar_id.noke \
or self.shift_one_min_sign_in != self.parent_calendar_id.shift_one_min_sign_in \
or self.shift_one_max_sign_in != self.parent_calendar_id.shift_one_max_sign_in \
or self.shift_one_min_sign_out != self.parent_calendar_id.shift_one_min_sign_out \
or self.shift_one_max_sign_out != self.parent_calendar_id.shift_one_max_sign_out \
or self.shift_one_working_hours != self.parent_calendar_id.shift_one_working_hours \
or self.shift_two_min_sign_in != self.parent_calendar_id.shift_two_min_sign_in \
or self.shift_two_max_sign_in != self.parent_calendar_id.shift_two_max_sign_in \
or self.shift_two_min_sign_out != self.parent_calendar_id.shift_two_min_sign_out \
or self.shift_two_max_sign_out != self.parent_calendar_id.shift_two_max_sign_out \
or self.shift_two_working_hours != self.parent_calendar_id.shift_two_working_hours \
or (self.special_days\
and (len(self.special_days) != len(self.parent_calendar_id.special_days)\
or self.calendar_special_days_change())) \
or (self.special_days_partcial \
and (len(self.special_days_partcial) != len(self.parent_calendar_id.special_days_partcial) \
or self.calendar_special_days_change())) \
or not ((len(self.parent_calendar_id.full_day_off) == len(self.full_day_off) ==
len(list(set(self.full_day_off.mapped('name'))
& set(self.parent_calendar_id.full_day_off.mapped('name'))))))\
or not ((len(self.parent_calendar_id.shift_day_off) == len(self.shift_day_off) ==
len(list(set(self.shift_day_off.mapped('name'))
& set(self.parent_calendar_id.shift_day_off.mapped('name')))))):
self.state = 'confirm'
self.parent_calendar_id.employee_ids.write({'resource_calendar_id': self.id})
self.parent_calendar_id.active = False
for com in self.env['res.company'].search([('resource_calendar_id', '=', self.parent_calendar_id.id)]):
com.resource_calendar_id = self.parent_calendar_id.id
else:
self.parent_calendar_id.write({'attendance_ids': [(2, at.id, False) for at in self.parent_calendar_id.attendance_ids],})
self.parent_calendar_id.write({
'name': self.parent_calendar_id.name != self.name and self.name or self.parent_calendar_id.name,
'deduction_rule': self.parent_calendar_id.deduction_rule.id != self.deduction_rule.id\
and self.deduction_rule.id or self.parent_calendar_id.deduction_rule.id,
'active': self.parent_calendar_id.active != self.active and self.active or self.parent_calendar_id.active,
'attendance_ids': [(4, at.copy().id) for at in self.attendance_ids],
'state': 'confirm'
})
calendar_id = self.parent_calendar_id.id
self.unlink()
cxt = dict(self.env.context)
cxt['form_view_initial_mode'] = 'readonly'
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'res_model': 'resource.calendar',
'view_mode': 'form',
'res_id': calendar_id,
'context': cxt,
}
def act_update(self):
self.ensure_one()
new = self.copy({'parent_calendar_id': self.id,
'state': 'draft',
'full_day_off': [(4, wknd.copy().id) for wknd in self.full_day_off],
'special_days': [(4, spd.copy().id) for spd in self.special_days],
'attendance_ids': [(4, at.copy().id) for at in self.attendance_ids],
})
self.write({'state': 'update',})
cxt = dict(self.env.context)
cxt['form_view_initial_mode'] = 'edit'
cxt['force_detailed_view'] = True
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'resource.calendar',
'res_id': new.id,
'context': cxt,
}
@api.constrains('noke', 'is_full_day', 'full_min_sign_in', 'full_max_sign_in', 'full_min_sign_out',
'full_max_sign_out', )
def full_time_constrains(self):
for rec in self:
if rec.is_full_day and not rec.noke:
value = rec.shift_cons_check(rec.full_min_sign_in, rec.full_max_sign_in, rec.full_min_sign_out,
rec.full_max_sign_out)
if value == 1:
raise ValidationError(_("Max sign in should be greater than or equal min sign in"))
if value == 2:
raise ValidationError(_("min sign out should be greater than or equal min sign in"))
if value == 3:
raise ValidationError(_("Max sign out should be greater than or equal min sign out"))
@api.onchange('shift_one_min_sign_in', 'shift_one_min_sign_out', 'shift_two_min_sign_in',
'shift_two_min_sign_out')
def work_hours(self):
self.shift_one_working_hours = self.get_shift_working_hour(self.shift_one_min_sign_in,
self.shift_one_min_sign_out)
self.shift_two_working_hours = self.get_shift_working_hour(self.shift_two_min_sign_in,
self.shift_two_min_sign_out)
def get_shift_working_hour(self, min_in, min_out):
time_start = datetime.strptime(str('{0:02.0f}:{1:02.0f}'.format(*divmod(float(min_in) * 60, 60))), "%H:%M")
time_end = datetime.strptime(str('{0:02.0f}:{1:02.0f}'.format(*divmod(float(min_out) * 60, 60))), "%H:%M")
diff = time_end - time_start
result = diff.seconds / 3600
return result
def shift_cons_check(self, min_in, max_in, min_out, max_out):
# 00:00 issue
min_in = min_in + 24 if min_in < 1 else min_in
max_in = max_in + 24 if max_in < 1 else max_in
min_out = min_out + 24 if min_out < 1 else min_out
max_out = max_out + 24 if max_out < 1 else max_out
if min_in > max_in:
return 1
if min_in > min_out or max_in > min_out:
return 2
if min_out > max_out:
return 3
@api.constrains('noke', 'is_full_day', 'shift_one_min_sign_in', 'shift_one_max_sign_in', 'shift_one_min_sign_out',
'shift_one_max_sign_out', )
def shift_one_constrains(self):
for rec in self:
if not rec.is_full_day and not rec.noke:
value = self.shift_cons_check(rec.shift_one_min_sign_in, rec.shift_one_max_sign_in,
rec.shift_one_min_sign_out, rec.shift_one_max_sign_out)
if value == 1:
raise ValidationError(_("Max sign in should be greater than or equal min sign in in shift one"))
if value == 2:
raise ValidationError(_("min sign out should be greater than or equal min sign in in shift one"))
if value == 3:
raise ValidationError(_("Max sign out should be greater than or equal min sign out in shift one"))
@api.constrains('noke', 'is_full_day', 'shift_two_min_sign_in', 'shift_two_max_sign_in',
'shift_two_min_sign_out',
'shift_two_max_sign_out')
def shift_two_constrains(self):
for rec in self:
if not rec.is_full_day and not rec.noke:
value = self.shift_cons_check(rec.shift_two_min_sign_in, rec.shift_two_max_sign_in,
rec.shift_two_min_sign_out, rec.shift_two_max_sign_out)
if value == 1:
raise ValidationError(_("Max sign in should be greater than or equal min sign in in shift two"))
if value == 2:
raise ValidationError(_("min sign out should be greater than or equal min sign in in shift two"))
if value == 3:
raise ValidationError(_("Max sign out should be greater than or equal min sign out in shift two"))
class DaysOff(models.Model):
_name = 'days.off'
name = fields.Selection(selection=[('saturday', 'Saturday'),
('sunday', 'Sunday'),
('monday', 'Monday'),
('tuesday', 'Tuesday'),
('wednesday', 'Wednesday'),
('thursday', 'Thursday'),
('friday', 'Friday')], string='Day Off')
# relation fields
day_off_attendance = fields.Many2one('resource.calendar')
class SpecialDays(models.Model):
_name = 'attendance.special.days'
name = fields.Selection(selection=[('saturday', 'Saturday'),
('sunday', 'Sunday'),
('monday', 'Monday'),
('tuesday', 'Tuesday'),
('wednesday', 'Wednesday'),
('thursday', 'Thursday'),
('friday', 'Friday')], string='Day Off')
start_sign_in = fields.Float(string='Start Sign In')
end_sign_in = fields.Float(string='End Sign In')
start_sign_out = fields.Float(string='Start Sign Out')
end_sign_out = fields.Float(string='End Sign Out')
working_hours = fields.Float(string='Working Hours')
# relation fields
special_days_attendance = fields.Many2one('resource.calendar')
date_from = fields.Date(string='Date From')
date_to = fields.Date(string='Date To')
shift = fields.Selection(selection=[('one', 'First Shift'), ('two', 'Second Shift')], string='Shift')
class ActionReason(models.Model):
_name = 'attendance.action.reason'
name = fields.Char(string='Reason')
type = fields.Selection(selection=[('sign_in', ' Sign In'),
('sign_out', 'Sign Out')], string='Action Type')
class Attendance(models.Model):
_name = 'attendance.attendance'
employee_id = fields.Many2one('hr.employee', string="Employee", domain="[('state', '=', 'open')]", required=True,
ondelete='cascade', index=True)
action = fields.Selection(selection=[('sign_in', ' Sign In'),
('sign_out', 'Sign Out'),
('action', 'Action')], string='Action', default='sign_in')
taken = fields.Boolean(string='Taken')
action_type = fields.Selection(selection=[('manual', 'Manual'),
('finger_print', 'Finger Print')], string='Action Type')
action_date = fields.Date(string='Action Date', compute='compute_date', store=True)
#name = fields.Datetime(string='Date', default=datetime.utcnow())
name = fields.Datetime(string='Date', default=lambda self: fields.datetime.now())
action_reason = fields.Many2one('attendance.action.reason', string='Action Reason')
employee_number = fields.Char(related='employee_id.emp_no', string='Employee Number',store=True)
@api.depends('name')
def compute_date(self):
for item in self:
item.action_date = datetime.now().date()
datee = datetime.strptime(str(item.name.strftime(DATETIME_FORMAT)), "%Y-%m-%d %H:%M:%S") + timedelta(
hours=3)
if datee:
dt = datee
item.action_date = dt.strftime('%Y-%m-%d')
else:
item.action_date = False
class HrEmployee(models.Model):
_inherit = 'hr.employee'
def attendance_action_change(self):
res = super(HrEmployee, self).attendance_action_change()
action_date = datetime.utcnow()
if self.state == 'open':
if self.attendance_state != 'checked_in':
vals = {
'employee_id': self.id,
'name': action_date,
'action': 'sign_out',
'action_date': action_date,
}
else:
vals = {
'employee_id': self.id,
'name': action_date,
'action': 'sign_in',
'action_date': action_date,
}
self.env['attendance.attendance'].create(vals)
return res
def _compute_attendance_state(self):
for rec in self:
last = rec.env['attendance.attendance'].search([('employee_id', '=', rec.id), ], order='name desc', limit=1)
if last.action == 'sign_in':
rec.attendance_state = 'checked_in'
else:
rec.attendance_state = 'checked_out'

View File

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from odoo import models, fields, api, _, exceptions
class HrAttendanceRegister(models.Model):
_name = 'hr.attendance.register'
_rec_name = 'register_date'
_inherit = ['mail.thread', 'mail.activity.mixin']
action_type = fields.Selection(selection=[('sign_in', _('Sign In')),
('sign_out', _('Sign Out'))], string='Action Type')
action_date = fields.Datetime(string='Attendance Date')
from_hr_depart = fields.Boolean()
department_id = fields.Many2one(related="employee_id.department_id", readonly=True)
job_id = fields.Many2one(related="employee_id.job_id", readonly=True)
employee_id = fields.Many2one('hr.employee', index=True, default=lambda item: item.get_user_id())
note_text = fields.Text()
register_date = fields.Date(string='Register Date', default=lambda self: fields.Date.today())
state = fields.Selection(
[('draft', _('Draft')),
('send', _('Send')),
('direct_manager', _('Direct Manager')),
('hr_manager', _('HR Manager')),
('refused', _('Refused'))], default="draft")
date = fields.Date(string='Date')
company_id = fields.Many2one(related='employee_id.company_id')
def unlink(self):
for rec in self:
if rec.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrAttendanceRegister, self).unlink()
@api.constrains('action_date')
def compute_date(self):
for item in self:
today = fields.Date.from_string(fields.Date.today())
datee = item.action_date
if datee:
attendance_date = datetime.strptime(str(datee), "%Y-%m-%d %H:%M:%S")
currnt_hour = datetime.now().hour + 3
hour_attendance = attendance_date.hour + 3
currnt_date = datetime.strptime(str(datee), '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')
deff_days = (today - fields.Date.from_string(currnt_date)).days
if deff_days > 2:
raise exceptions.Warning(_('You can not Register Attendance Before Tow Days'))
if deff_days < 0:
raise exceptions.Warning(_('You can not Register Attendance After Today'))
# item.date = currnt_date
priv_register = self.env['hr.attendance.register'].search([('employee_id', '=', item.employee_id.id),('id','!=',item.id)])
for reg in priv_register:
date = datetime.strptime(str(reg.action_date), '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')
if date == currnt_date:
raise exceptions.Warning(_('You can not Register Attendance More Than once in The Same day'))
if currnt_date > str(item.register_date):
raise exceptions.Warning(_('You can not Register Attendance At Future Date'))
if hour_attendance > currnt_hour:
raise exceptions.Warning(_('You can not Register Attendance Before The Time'))
def draft_state(self):
self.state = "draft"
def button_submit(self):
self.state = "send"
def direct_manager(self):
self.state = "direct_manager"
def hr_manager(self):
extract_date = datetime.strptime(str(self.action_date), "%Y-%m-%d %H:%M:%S").date()
self.env['attendance.attendance'].create({
'employee_id': self.employee_id.id,
'name': self.action_date,
'action': self.action_type,
'action_date': self.action_date.date(),
'action_type': 'manual',
})
self.state = "hr_manager"
self.call_cron_function()
def set_to_draft(self):
for item in self:
attendances = self.env['attendance.attendance'].search([('action_date', '=', item.action_date),
('employee_id', '=', item.employee_id.id)],
order="name asc")
for attendance in attendances:
if attendance.name == item.action_date:
attendance.unlink()
self.state = "draft"
self.call_cron_function()
def call_cron_function(self):
date = datetime.strptime(str(self.action_date), "%Y-%m-%d %H:%M:%S")
self.env['hr.attendance.transaction'].process_attendance_scheduler_queue(self.action_date, self.employee_id)
def refused(self):
self.state = "refused"
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False

View File

@ -0,0 +1,334 @@
# -*- coding: utf-8 -*-
from __future__ import division
from datetime import datetime, timedelta
from odoo import models, fields, _, exceptions
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT
class HrAttendanceReport(models.Model):
_name = 'hr.attendance.report'
_rec_name = 'date_from'
_inherit = ['mail.thread', 'mail.activity.mixin']
date_from = fields.Date()
date_to = fields.Date()
line_ids = fields.One2many('hr.attendance.report.line', 'line_id')
state = fields.Selection(
[('draft', _('Draft')), ('generated', _('Generated')),
# ('reviewed', _('Reviewed')),
('confirmed', _('HR Manager Approval')),
('approved', _('Approved')), ('refused', _('Refused'))], default="draft")
calendar_ids = fields.Many2many('resource.calendar', string='Calendars')
deduct_date_from = fields.Date()
deduct_date_to = fields.Date()
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
def unlink(self):
for rec in self:
if rec.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrAttendanceReport, self).unlink()
def draft_state(self):
self.state = "draft"
def reviewed(self):
self.state = "reviewed"
def confirmed(self):
self.state = "confirmed"
def set_to_draft(self):
for line in self.line_ids:
if line.advantage_id:
line.advantage_id.draft()
line.advantage_id.unlink()
self.line_ids.unlink()
# self.write({'line_ids': [(5,)]})
self.state = "draft"
def approved(self):
for line in self.line_ids:
employee_contract = line.env['hr.contract'].search([('employee_id', '=', line.employee_name.id),
('state', '=', 'program_directory')])
if employee_contract and line.employee_name.finger_print:
advantage_arc = line.env['contract.advantage'].create({
'benefits_discounts': line.employee_name.resource_calendar_id.deduction_rule.id,
'type': 'customize',
'date_from': self.deduct_date_from,
'date_to': self.deduct_date_to,
'amount': line.total_deduction,
'employee_id': line.employee_name.id,
'contract_advantage_id': line.employee_name.contract_id.id,
'out_rule': True,
'state': 'confirm',
'comments': 'Absence Deduction'})
line.advantage_id = advantage_arc.id
self.state = "approved"
def refused(self):
for line in self.line_ids:
line.advantage_id.draft()
line.advantage_id.unlink()
self.state = "refused"
def calcualte_flexible_transaction(self, transactions):
planed_hours = sum(transactions.filtered(lambda t: t.public_holiday == False).mapped('plan_hours'))
office_hours = sum(transactions.mapped('office_hours'))
permission_hours = sum(transactions.filtered(
lambda t: t.personal_permission_id != False).mapped('total_permission_hours'))
mission_hours = sum(transactions.filtered(
lambda t: t.official_id != False
and t.official_id.mission_type.duration_type == 'hours').mapped('total_mission_hours'))
mission_by_days_hours = sum(transactions.filtered(
lambda t: t.official_id != False
and t.official_id.mission_type.duration_type == 'days').mapped('total_mission_hours'))
leave_hours = sum(transactions.filtered(lambda t: t.normal_leave == True).mapped('total_leave_hours'))
working_hours = office_hours + permission_hours + mission_hours + mission_by_days_hours + leave_hours
missed_hours = planed_hours - working_hours
if missed_hours < 0:
missed_hours = 0
return {'leaves': leave_hours, 'missed_hours': missed_hours, 'mission_by_days': mission_by_days_hours}
def generate_report(self):
transaction_values = {}
item_list, mixed_calendar_emps = [], []
module = self.env['ir.module.module'].sudo()
official_mission_module = module.search([('state', '=', 'installed'), ('name', '=', 'exp_official_mission')])
personal_permission_module = module.search([('state', '=', 'installed'), ('name', '=', 'employee_requests')])
holidays_module = module.search([('state', '=', 'installed'), ('name', '=', 'hr_holidays_public')])
transaction_pool = self.env['hr.attendance.transaction']
reason_pool = self.env['hr.reasons.lateness']
domain = self._context.get('emp_id', False) and [('id', '=', self._context.get('emp_id'))] or []
emps = self.env['hr.employee'].search(domain)
trans_domain = [('date', '>=', self.date_from), ('date', '<=', self.date_to), ('attending_type', '=', 'in_cal')]
if self.calendar_ids: trans_domain += [('calendar_id', 'in', self.calendar_ids.ids)]
for employee in emps:
missed_hours, wasted_hours, absent, total_mission, leaves, hours_per_day, count, \
additional_hours = 0, 0, 0, 0, 0, 0, 0, 0
emp_trans_dom = trans_domain.copy() + [('employee_id', '=', employee.id)]
attendance_transaction = transaction_pool.search(emp_trans_dom)
if len(attendance_transaction.mapped('calendar_id')) > 1:
mixed_calendar_emps.append(employee.id)
continue
else:
emp_calendar = attendance_transaction and attendance_transaction[0].calendar_id\
or employee.resource_calendar_id
if emp_calendar.is_flexible:
flexible_trans = attendance_transaction.filtered(lambda t: t.public_holiday == False)
no_of_days = len(set(flexible_trans.mapped('date')))
flexible_days = emp_calendar.number_of_flexi_days
if no_of_days >= flexible_days:
ord_trans_dates = sorted(set(flexible_trans.mapped('date')),
key=lambda x: datetime.strptime(x, DATE_FORMAT))
index = len(ord_trans_dates) > flexible_days and flexible_days - 1 or len(ord_trans_dates) - 1
df = fields.Date.from_string(self.date_from)
while no_of_days >= flexible_days:
dt = ord_trans_dates[index]
current_trans = attendance_transaction.filtered(lambda t: str(df) <= t.date <= str(dt))
hours_dict = self.calcualte_flexible_transaction(current_trans)
total_mission += hours_dict['mission_by_days']
missed_hours += hours_dict['missed_hours']
leaves += hours_dict['leaves']
additional_hours += hours_dict['additional_hours']
df = fields.Date.from_string(dt) + timedelta(1)
index = index + flexible_days > len(ord_trans_dates) and len(ord_trans_dates) or index + flexible_days
no_of_days -= flexible_days
else:
if no_of_days and no_of_days < flexible_days:
current_trans = attendance_transaction.filtered(lambda t: str(df) <= t.date <= self.date_to)
hours_dict = self.calcualte_flexible_transaction(current_trans)
total_mission += hours_dict['mission_by_days']
missed_hours += hours_dict['missed_hours']
leaves += hours_dict['leaves']
additional_hours += hours_dict['additional_hours']
else:
hours_dict = self.calcualte_flexible_transaction(attendance_transaction)
missed_hours = hours_dict['missed_hours']
leaves, total_mission = hours_dict['leaves'], hours_dict['mission_by_days']
working_hours_flexible_days = emp_calendar.total_flexible_hours
values = {
'employee_name': employee.id,
'delay': 0.0,
'leave': leaves,
'additional_hours': 0.0,
'exists': 0.0,
'extra_break_duration': 0.0,
'absent': missed_hours,
'mission_by_days': total_mission,
'absent_days_by_hr': 0.0,
'total_hours': missed_hours,
'dummy_field': missed_hours,
'total_amount': employee.contract_id.total_allowance,
'amount_per_hour': employee.contract_id.total_allowance / working_hours_flexible_days,
'total_deduction': missed_hours * (
employee.contract_id.total_allowance / working_hours_flexible_days)
}
item_list.append(values)
elif not emp_calendar.is_flexible:
lateness_reasons = reason_pool.search([('latest_date', '>=', self.date_from),
('latest_date', '<=', self.date_to),
('employee_id', '=', employee.id),
('state', '=', 'hr_manager')])
emp_trans = attendance_transaction.filtered(lambda t: t.public_holiday == False)
for attendance in emp_trans:
lateness, early_exist, extra_break_duration, hours, additional_hours = 0.0, 0.0, 0.0, 0.0, 0.0
total_permission, total_mission_by_hour, total_mission_by_day, total_leaves = 0.0, 0.0, 0.0, 0.0
total_absent, lateness_hours_by_hr, get_total_amount = 0.0, 0.0, 0.0
transaction_values['id'], transaction_values['name'] = attendance.employee_id.id, attendance.employee_id.name
total_hours_for_two_shifts = emp_calendar.shift_one_working_hours + \
emp_calendar.shift_two_working_hours
if lateness_reasons:
if attendance.lateness > 0.0 or attendance.early_exit > 0.0:
for late in lateness_reasons:
if attendance.date == late.latest_date:
lateness_hours_by_hr += (attendance.lateness + attendance.early_exit)
if attendance.approve_lateness: lateness += attendance.lateness
if attendance.approve_exit_out: early_exist += attendance.early_exit
if personal_permission_module and attendance.approve_personal_permission:
total_permission += attendance.total_permission_hours
if official_mission_module and attendance.is_official:
if attendance.official_id.mission_type.duration_type == 'days':
total_mission_by_day += attendance.total_mission_hours
else:
total_mission_by_hour += attendance.total_mission_hours
if holidays_module and attendance.normal_leave:
total_leaves += attendance.total_leave_hours
hours += attendance.official_hours
extra_break_duration += attendance.break_duration
additional_hours += attendance.additional_hours
if attendance.is_absent:
total_absent += attendance.plan_hours
if attendance.calendar_id.is_full_day:
total_absent += attendance.calendar_id.break_duration
elif attendance.sequence == 1:
total_absent += attendance.calendar_id.shift_one_break_duration
elif attendance.sequence == 2:
total_absent += attendance.calendar_id.shift_two_break_duration
else:
working_hours = total_permission + total_mission_by_hour + hours + attendance.carried_hours
absence_hours = attendance.plan_hours - working_hours
total_absent += absence_hours > 0 and absence_hours or 0
if total_absent == 0:
get_total_hours = (
lateness + early_exist + extra_break_duration + total_absent) - lateness_hours_by_hr
else:
get_total_hours = (total_absent - lateness_hours_by_hr)
if get_total_hours < 0:
get_total_hours = 0
if attendance.employee_id.contract_id.state == 'program_directory':
get_total_amount = attendance.employee_id.contract_id.total_allowance
if emp_calendar.is_full_day:
working_hours_per_week = emp_calendar.working_hours * emp_calendar.working_days
get_amount_per_hour = get_total_amount / working_hours_per_week
else:
get_amount_per_hour = get_total_amount / (
total_hours_for_two_shifts * emp_calendar.working_days)
values = {
'employee_name': attendance.employee_id.id,
'delay': lateness,
'leave': total_leaves,
'exists': early_exist,
'extra_break_duration': extra_break_duration,
'absent': total_absent,
'mission_by_days': total_mission_by_day,
'absent_days_by_hr': lateness_hours_by_hr,
'total_hours': get_total_hours,
'dummy_field': get_total_hours,
'total_amount': get_total_amount,
'amount_per_hour': get_amount_per_hour,
'total_deduction': get_total_hours * get_amount_per_hour,
'additional_hours': additional_hours
}
item_list.append(values)
from itertools import groupby, tee
from operator import itemgetter
grouper = itemgetter("employee_name")
result = []
for key, grp in groupby(sorted(item_list, key=grouper), grouper):
if not isinstance(key, tuple):
key = [key]
temp_dict = dict(zip(["employee_name"], key))
grp1, grp2, grp3, grp4, grp5, grp6, grp7, grp8, grp9, grp10, grp11, grp12, grp13, grp14, grp15 = tee(grp, 15)
temp_dict["delay"] = sum(item["delay"] for item in grp1)
temp_dict["leave"] = sum(item1["leave"] for item1 in grp2)
temp_dict["mission_by_days"] = sum(item1["mission_by_days"] for item1 in grp14)
temp_dict["absent"] = sum(item1["absent"] for item1 in grp3) - (
temp_dict["leave"] + temp_dict["mission_by_days"])
temp_dict["exists"] = sum(item1["exists"] for item1 in grp4)
temp_dict["extra_break_duration"] = sum(item1["extra_break_duration"] for item1 in grp5)
temp_dict["absent_days_by_hr"] = sum(item1["absent_days_by_hr"] for item1 in grp6)
temp_dict["total_hours"] = sum(item["total_hours"] for item in grp7) - (
temp_dict["leave"] + temp_dict["mission_by_days"])
temp_dict["dummy_field"] = sum(item["dummy_field"] for item in grp13)
temp_dict["total_amount"] = sum(item["total_amount"] for item in grp8) / len(list(grp9))
temp_dict["amount_per_hour"] = sum(item["amount_per_hour"] for item in grp10) / len(list(grp11))
############# re chick total_deduction
temp_dict["total_deduction"] = temp_dict["absent"]*temp_dict["amount_per_hour"]
#temp_dict["total_deduction"] = sum(item["total_deduction"] for item in grp12)
temp_dict["additional_hours"] = sum(item["additional_hours"] for item in grp15)
result.append(temp_dict)
self.write({'line_ids': [(0, 0, val) for val in result]})
self.state = "generated"
if mixed_calendar_emps:
self.manage_mixed_calendar(mixed_calendar_emps)
def manage_mixed_calendar(self, emp_calendars):
for emp in emp_calendars:
trans = self.env['hr.attendance.transaction'].search([('date', '>=', self.date_from),
('date', '<=', self.date_to),
('employee_id', '=', emp)])
calendar_ids = trans.mapped('calendar_id').ids
recs = self.env['hr.attendance.report']
for cal in calendar_ids:
tdates = list(set(trans.filtered(lambda l: l.calendar_id.id == cal).mapped('date')))
tdates.sort()
ldate = fields.Date.from_string(tdates[0]) + timedelta(len(tdates) - 1)
if ldate == fields.Date.from_string(tdates[-1]):
rec = self.create({'date_from': tdates[0], 'date_to': tdates[-1]})
rec.with_context(emp_id=emp).generate_report()
recs += rec
else:
ranges, date_range, base = [], [], tdates.pop(0)
date_range.append(base)
bdate = fields.Date.from_string(base) + timedelta(1)
for dt in tdates:
if bdate == fields.Date.from_string(dt):
date_range.append(dt)
bdate += timedelta(1)
if dt == tdates[-1]:
ranges.append(date_range)
else:
ranges.append(date_range)
date_range, bdate = [dt], fields.Date.from_string(dt) + timedelta(1)
for range in ranges:
rec = self.create({'date_from': range[0], 'date_to': range[-1]})
rec.with_context(emp_id=emp).generate_report()
recs += rec
main_rec = recs[0]
sum_recs = recs.filtered(lambda r: r.id != main_rec.id)
sum_line = main_rec.line_ids[0]
sum_line.write({
'line_id': self.id,
'delay': sum_line.delay + sum(sum_recs.mapped('line_ids.delay')),
'leave': sum_line.leave + sum(sum_recs.mapped('line_ids.leave')),
'absent': sum_line.absent + sum(sum_recs.mapped('line_ids.absent')),
'exists': sum_line.exists + sum(sum_recs.mapped('line_ids.exists')),
'total_hours': sum_line.total_hours + sum(sum_recs.mapped('line_ids.total_hours')),
'dummy_field': sum_line.dummy_field + sum(sum_recs.mapped('line_ids.dummy_field')),
'total_deduction': sum_line.total_deduction + sum(sum_recs.mapped('line_ids.total_deduction')),
'absent_days_by_hr': sum_line.absent_days_by_hr + sum(sum_recs.mapped('line_ids.absent_days_by_hr')),
'mission_by_days': sum_line.mission_by_days + sum(sum_recs.mapped('line_ids.mission_by_days')),
'extra_break_duration': sum_line.extra_break_duration + sum(
sum_recs.mapped('line_ids.extra_break_duration')),
'additional_hours': sum_line.additional_hours + sum(sum_recs.mapped('line_ids.additional_hours')),
})
recs.unlink()

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class HrAttendanceReportLine(models.Model):
_name = 'hr.attendance.report.line'
employee_name = fields.Many2one(comodel_name='hr.employee')
delay = fields.Float()
leave = fields.Float(string='Holiday Hours')
exists = fields.Float()
extra_break_duration = fields.Float()
absent = fields.Float(string='Absent Hours')
mission_by_days = fields.Float(string='Mission Hours')
line_id = fields.Many2one(comodel_name='hr.attendance.report')
absent_days_by_hr = fields.Float(string='Absent Hours By HR')
dummy_field = fields.Float()
total_hours = fields.Float(string='Total Absence Hours') # get total hours in month from attendance configuration
total_amount = fields.Float(string='Total Salary') # get from total allowance in contract
amount_per_hour = fields.Float() # get from total_amount / total_hours
total_deduction = fields.Float() # get from delay+leave+absent * amount_per_hour
additional_hours = fields.Float(string='Additional Hours', default=0)
advantage_id = fields.Many2one(comodel_name='contract.advantage', string='Deduction Employee')
@api.onchange('absent_days_by_hr')
def onchange_absent_days_by_hr(self):
for item in self:
if item.absent == 0:
item.dummy_field = item.delay + item.exists + item.extra_break_duration + item.absent
hours = item.dummy_field - item.absent_days_by_hr
if hours < 0:
hours = 0
deduction = hours * item.amount_per_hour
return {'value': {'total_hours': hours,
'total_deduction': deduction}}
else:
item.dummy_field = item.absent
hourss = item.dummy_field - item.absent_days_by_hr
if hourss < 0:
hourss = 0
deduction = hourss * item.amount_per_hour
return {'value': {'total_hours': hourss,
'total_deduction': deduction}}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import models, fields, _, exceptions
class HrReasonsLateness(models.Model):
_name = 'hr.reasons.lateness'
_rec_name = 'reasons'
_inherit = ['mail.thread', 'mail.activity.mixin']
request_date = fields.Date(default=lambda self: fields.Date.today())
latest_date = fields.Date()
reasons = fields.Text()
from_hr_depart = fields.Boolean()
department_id = fields.Many2one(related="employee_id.department_id", readonly=True)
job_id = fields.Many2one(related="employee_id.job_id", readonly=True)
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id())
state = fields.Selection([('draft', _('Draft')),
('send', _('Send')),
('direct_manager', _('Direct Manager')),
('hr_manager', _('HR Manager')),
('refused', _('Refused'))], default="draft")
company_id = fields.Many2one(related='employee_id.company_id')
def unlink(self):
for rec in self:
if rec.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrReasonsLateness, self).unlink()
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
def draft_state(self):
self.state = "draft"
self.call_cron_function()
def button_submit(self):
self.state = "send"
def hr_manager(self):
self.state = "hr_manager"
self.call_cron_function()
def call_cron_function(self):
transaction = self.env['hr.attendance.transaction']
start_date = self.request_date
end_date = self.latest_date
delta = end_date - start_date
for i in range(delta.days + 1):
day = start_date + timedelta(days=i)
transaction.process_attendance_scheduler_queue(day, self.employee_id)
def direct_manager(self):
self.state = "direct_manager"
def set_to_draft(self):
self.state = "draft"
self.call_cron_function()
def refused(self):
self.state = "refused"

View File

View File

@ -0,0 +1,260 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="employee_attendance_report_template">
<div class="page" style="font-size:17pt">
<center><h2 style="font-weight:bold">تقرير الحضور و الانصراف للعام </h2></center>
<br/>
<t t-foreach="mykey" t-as="key">
<table class="table table-condensed">
<thead>
<tr>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:30%;text-align:center;">
الموظف
</th>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:30%;text-align:center;">
مجموع التأخيرات
</th>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:20%;text-align:center;">
مجموع الانصراف المبكر
</th>
</tr>
</thead>
<tbody>
<tr>
<td style=" border-bottom: 1px solid white; border-left: 1px solid white;border-right: 1px solid white;padding: 1px; width:20%;font-size:0.8em;background-color: white;color: black; text-align:center">
<t t-esc="key"/>
</td>
<td style=" border-bottom: 1px solid white; border-left: 1px solid white;border-right: 1px solid white;padding: 1px; width:20%;font-size:0.8em;background-color: white;color: black; text-align:center">
<t t-esc="total[key]['total_lateness']"/>
</td>
<td style=" border-bottom: 1px solid white; border-right: 1px solid white;padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center">
<t t-esc="total[key]['total_early_exit']"/>
</td>
</tr>
</tbody>
</table>
</t>
</div>
</template>
<template id="absent_attendance_report_template">
<div class="page" style="font-size:14pt">
<center><h2 style="font-weight:bold">
تقرير الغياب
<br/>
جميع الموظفين- تفصيلي
</h2></center>
<br/>
<table style="width:100%">
<tr>
<td><h4 style="font-weight:bold"> من تاريخ </h4></td>
<td><t t-esc="date_start"/></td>
<td><h4 style="font-weight:bold">إلى </h4></td>
<td><t t-esc="date_end"/></td>
</tr>
</table>
<br/>
<br/>
<t t-foreach="mykey" t-as="key">
<table style="width:100%">
<tr>
<td style="font-weight:bold">الادارة</td>
<td style="color:black"><t t-esc="key"/></td>
</tr>
</table>
<br/>
<table class="table table-condensed">
<thead>
<tr>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:30%;text-align:center;">
اسم الموظف
</th>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:30%;text-align:center;">
اليوم
</th>
<th style=" border: 1px solid white; padding: 1px; font-size:0.8em;background-color: white;color: black;width:20%;text-align:center;">
التاريخ
</th>
<th style=" border: 1px solid white; padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center;">
ملاحظات
</th>
</tr>
</thead>
<tbody>
<t t-foreach="data[key]" t-as="line">
<tr>
<td style=" border-bottom: 1px solid gray; border-left: 1px solid white;border-right: 1px solid white;padding: 1px; width:20%;font-size:0.8em;background-color: white;color: black; text-align:center">
<t t-esc="line['employee_name']"/>
</td>
<td style=" border-bottom: 1px solid gray; border-left: 1px solid white;border-right: 1px solid white;padding: 1px; width:20%;font-size:0.8em;background-color: white;color: black; text-align:center">
<t t-esc="line['day']"/>
</td>
<td style=" border-bottom: 1px solid gray; border-left: 1px solid white;padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center">
<t t-esc="line['date']"/>
</td>
<td style="border-bottom: 1px solid gray; border-left: 1px solid white;color:white;width:15%">.</td>
</tr>
</t>
</tbody>
</table>
</t>
</div>
</template>
<template id="late_attendance_report_template">
<div class="page" style="font-size:12pt">
<br/>
<center><h2 style="font-weight:bold">تقرير تاخير و خروج مبكر</h2></center>
<br/>
<table style="width:100%">
<tr>
<td><h4 style="font-weight:bold"> من تاريخ:</h4></td>
<td><t t-esc="date_start"/></td>
<td><h4 style="font-weight:bold"> الى:</h4></td>
<td><t t-esc="date_end"/></td>
</tr>
</table>
<br/>
<t t-foreach="mykey" t-as="key">
<table style="width:100%">
<tr>
<td style="font-weight:bold">الموظف </td>
<td style="color:black"><t t-esc="key"/></td>
</tr>
</table>
<br/>
<br/>
<table class="table table-condensed">
<thead>
<tr>
<th style=" border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: white;color: black;width:15%;text-align:center;">
التاريخ
</th>
<th style=" border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: white;color: black;width:15%;text-align:center;">
وقت الدخول
</th>
<th style=" border: 1px solid gray; padding: 1px;font-size:0.8em;background-color: white;color: black;width:15%;text-align:center;">
وفت الخروج
</th>
<th style=" border: 1px solid gray; padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center;">
تأخير
</th>
<th style=" border: 1px solid gray; padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center;">
إنصراف مبكر
</th>
<th style=" border: 1px solid gray; padding: 1px;font-size:0.8em;background-color: white;color: black;width:15%;text-align:center;">
ملاحظة
</th>
</tr>
</thead>
<tbody>
<t t-foreach="data[key]" t-as="line">
<tr>
<td style="border: 1px solid gray;padding: 1px; width:15%;font-size:0.8em;background-color: white;color: black; text-align:center">
<t t-esc="line['date']"/>
</td>
<td style="border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;width:15%;text-align:center">
<t t-esc="'%02d:%02d' % (int(str(line['sig_in']).split('.')[0]), int(float(str('%.2f' % line['sig_in']).split('.')[1])/100*60))"/>
</td>
<td style="border-right: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center">
<t t-esc= "'%02d:%02d' % (int(str(line['sig_out']).split('.')[0]), int(float(str('%.2f' % line['sig_out']).split('.')[1])/100*60))"/>
</td>
<td style="border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;width:20%;text-align:center">
<t t-esc="'%02d:%02d' % (int(str(line['lateness']).split('.')[0]), int(float(str('%.2f' % line['lateness']).split('.')[1])/100*60))"/>
</td>
<td style="border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;width:15%;text-align:center">
<t t-esc="'%02d:%02d' % (int(str(line['early_exit']).split('.')[0]), int(float(str('%.2f' % line['early_exit']).split('.')[1])/100*60))"/>
</td>
<td style="border: 1px solid gray; ;color:white;width:15%">.</td>
</tr>
</t>
</tbody>
<tr>
<td style="border-bottom: 1px solid white; ;color:white">.</td>
</tr>
<tfoot style="display:table-row-group;">
<tr>
<td colspan="6" style="border-bottom: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">المجموع</td>
</tr>
<tr>
<td style="border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
مجموع التأخيرات
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
<t t-esc="total[key]['total_lateness']" />
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
مجموع الخروج المبكر
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
<t t-esc="total[key]['total_early_exit']" />
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
الغيابات
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
<t t-esc="total[key]['total_absent']" />
</td>
</tr>
<tr>
<td colspan="2" style=" border: 1px solid gray; padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
عدم تسجيل دخول
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
<t t-esc="total[key]['total_not_sig_in']"/>
</td>
<td colspan="2" style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
عدم تسجيل خروج
</td>
<td style=" border: 1px solid gray;padding: 1px;font-size:0.8em;background-color: white;color: black;text-align:center;">
<t t-esc="total[key]['total_not_sig_out']"/>
</td>
</tr>
</tfoot>
</table>
</t>
</div>
</template>
<template id="general_attendances_report_temp">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<style type="text/css">
@font-face {
font-family: 'ae_AlMohanad';
src: local('ae_AlMohanad'), local('ae_AlMohanad'),
url('/attendances/static/fonts/ae_AlMohanad.ttf') format('truetype');
}
*{
font-family: ae_AlMohanad;
}
</style>
<t t-if="type == 'late'">
<t t-call="attendances.late_attendance_report_template"/>
</t>
<t t-if="type == 'absent'">
<t t-call="attendances.absent_attendance_report_template"/>
</t>
<t t-if="type == 'employee'">
<t t-call="attendances.employee_attendance_report_template"/>
</t>
</t>
</t>
</template>
<record id="general_attendance_action_report" model="ir.actions.report">
<field name="model">employee.attendance.report</field>
<field name="name">Attendance Report</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">attendances.general_attendances_report_temp</field>
</record>
<record id="general_attendance_action_xls" model="ir.actions.report">
<field name="model">employee.attendance.report</field>
<field name="name">Print to XLSX</field>
<field name="report_type">xlsx</field>
<field name="report_name">attendances.general_attendance_xls</field>
<field name="report_file">Attendance Report</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="hr_attendance_register_emp_rule" model="ir.rule">
<field name="name">Employee: views its own attendance register</field>
<field name="model_id" ref="model_hr_attendance_register"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_attendance_register_manager_rule" model="ir.rule">
<field name="name">Manager: views attendance register of its subordinates</field>
<field name="model_id" ref="model_hr_attendance_register"/>
<field name="domain_force">['|','|',('department_id.manager_id','=',False),
('department_id.manager_id.user_id','child_of', [user.id]),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager'))]"/>
</record>
<record id="hr_attendance_register_all_rule" model="ir.rule">
<field name="name">Manager: views attendance registers of all employee</field>
<field name="model_id" ref="model_hr_attendance_register"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_attendance.group_hr_attendance_user'))]"/>
</record>
<record id="hr_reasons_lateness_emp_rule" model="ir.rule">
<field name="name">Employee: views its lateness reasons</field>
<field name="model_id" ref="model_hr_reasons_lateness"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_reasons_lateness_manager_rule" model="ir.rule">
<field name="name">Manager: views lateness reasons of its subordinates</field>
<field name="model_id" ref="model_hr_reasons_lateness"/>
<field name="domain_force">['|','|',('department_id.manager_id','=',False),
('department_id.manager_id.user_id','child_of', [user.id]),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager'))]"/>
</record>
<record id="hr_reasons_lateness_all_rule" model="ir.rule">
<field name="name">Manager: views lateness reasons of all employees</field>
<field name="model_id" ref="model_hr_reasons_lateness"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_attendance.group_hr_attendance_user'))]"/>
</record>
<record id="hr_attendance_transaction_emp_rule" model="ir.rule">
<field name="name">Employee: views its attendance transactions</field>
<field name="model_id" ref="model_hr_attendance_transaction"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_attendance_transaction_manager_rule" model="ir.rule">
<field name="name">Manager: views attendance transactions of its subordinates</field>
<field name="model_id" ref="model_hr_attendance_transaction"/>
<field name="domain_force">['|','|',('employee_id.department_id.manager_id','=',False),
('employee_id.department_id.manager_id.user_id','child_of', [user.id]),
('employee_id.department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager'))]"/>
</record>
<record id="hr_attendance_transaction_all_rule" model="ir.rule">
<field name="name">Manager: views attendance transactions of all employees</field>
<field name="model_id" ref="model_hr_attendance_transaction"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_attendance.group_hr_attendance_user'))]"/>
</record>
<record id="hr_attendance_transaction_comp_rule" model="ir.rule">
<field name="name">appraisal result line company rule</field>
<field name="model_id" ref="model_hr_attendance_transaction"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="hr_attendance_register_comp_rule" model="ir.rule">
<field name="name">attendance register company rule</field>
<field name="model_id" ref="model_hr_attendance_register"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="hr_attendance_report_comp_rule" model="ir.rule">
<field name="name">hr.attendance.report company rule</field>
<field name="model_id" ref="model_hr_attendance_report"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record model="res.groups" id="base.group_user">
<field name="implied_ids" eval="[(4, ref('hr_attendance.group_hr_attendance'))]"/>
</record>
<record id="hr.group_hr_user" model="res.groups">
<field name="implied_ids" eval="[(4,ref('hr_attendance.group_hr_attendance_user'))]"/>
</record>
<record id="hr_attendance.hr_attendance_rule_attendance_employee" model="ir.rule">
<field name="name">user: modify own attendance only</field>
<field name="perm_read" eval="1"/>
</record>
<data noupdate="1">
<record id="make_invisible" model="res.groups">
<field name="name">Invisible</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,22 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_attendance_register_emp,hr.attendance.register.emp,model_hr_attendance_register,base.group_user,1,1,1,1
access_hr_reasons_lateness_emp,hr.reasons.lateness.emp,model_hr_reasons_lateness,base.group_user,1,1,1,1
access_hr_attendance_report_user,hr.attendance.report.user,model_hr_attendance_report,hr.group_hr_user,1,1,1,1
access_hr_attendance_report_user_line,hr.attendance.repor.line.user,model_hr_attendance_report_line,hr.group_hr_user,1,1,1,1
access_hr_attendance_report_man,hr.attendance.report.manag,model_hr_attendance_report,hr_base.group_general_manager,1,1,0,0
access_hr_attendance_report_user_line_man,hr.attendance.repor.line.manag,model_hr_attendance_report_line,hr_base.group_general_manager,1,1,0,0
access_hr_attendance_transaction_emp,hr.attendance.transaction.emp,model_hr_attendance_transaction,base.group_user,1,1,0,0
access_hr_attendance_transaction_user,hr.attendance.transaction.user,model_hr_attendance_transaction,hr.group_hr_user,1,1,1,0
access_days_off_user,days_off.user,model_days_off,hr.group_hr_user,1,1,1,0
access_days_off_manager,days_off.manager,model_days_off,hr_attendance.group_hr_attendance_manager,1,1,1,1
access_days_off_emp,days_off.emp,model_days_off,base.group_user,1,0,0,0
access_attendance_special_days_user,attendance.special.days.user,model_attendance_special_days,hr.group_hr_user,1,0,0,0
access_attendance_special_days_manager,attendance.special.days.manager,model_attendance_special_days,hr_attendance.group_hr_attendance_manager,1,1,1,1
access_attendance_action_reason_user,attendance.action.reason.user,model_attendance_action_reason,hr.group_hr_user,1,0,0,0
access_attendance_action_reason_manager,attendance.action.reason.manager,model_attendance_action_reason,hr_attendance.group_hr_attendance_manager,1,1,1,1
access_attendance_attendance,attendance_attendance,model_attendance_attendance,base.group_user,1,0,0,0
access_attendance_attendance_hr,attendance_attendance_hr,model_attendance_attendance,hr.group_hr_user,1,1,1,0
access_hr_attendance_wizard_hr,hr_attendance_wizard_hr,model_hr_attendance_wizard,hr.group_hr_user,1,1,1,0
access_employee_attendance_report_hr,employee_attendance_report_hr,model_employee_attendance_report,hr.group_hr_user,1,1,1,0
access_attendance_attendance_admin,attendance_attendance_admin,model_attendance_attendance,base.group_system,1,1,1,1
access_hr_attendance_transaction_admin,hr.attendance.transaction.admin,model_hr_attendance_transaction,base.group_system,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_attendance_register_emp hr.attendance.register.emp model_hr_attendance_register base.group_user 1 1 1 1
3 access_hr_reasons_lateness_emp hr.reasons.lateness.emp model_hr_reasons_lateness base.group_user 1 1 1 1
4 access_hr_attendance_report_user hr.attendance.report.user model_hr_attendance_report hr.group_hr_user 1 1 1 1
5 access_hr_attendance_report_user_line hr.attendance.repor.line.user model_hr_attendance_report_line hr.group_hr_user 1 1 1 1
6 access_hr_attendance_report_man hr.attendance.report.manag model_hr_attendance_report hr_base.group_general_manager 1 1 0 0
7 access_hr_attendance_report_user_line_man hr.attendance.repor.line.manag model_hr_attendance_report_line hr_base.group_general_manager 1 1 0 0
8 access_hr_attendance_transaction_emp hr.attendance.transaction.emp model_hr_attendance_transaction base.group_user 1 1 0 0
9 access_hr_attendance_transaction_user hr.attendance.transaction.user model_hr_attendance_transaction hr.group_hr_user 1 1 1 0
10 access_days_off_user days_off.user model_days_off hr.group_hr_user 1 1 1 0
11 access_days_off_manager days_off.manager model_days_off hr_attendance.group_hr_attendance_manager 1 1 1 1
12 access_days_off_emp days_off.emp model_days_off base.group_user 1 0 0 0
13 access_attendance_special_days_user attendance.special.days.user model_attendance_special_days hr.group_hr_user 1 0 0 0
14 access_attendance_special_days_manager attendance.special.days.manager model_attendance_special_days hr_attendance.group_hr_attendance_manager 1 1 1 1
15 access_attendance_action_reason_user attendance.action.reason.user model_attendance_action_reason hr.group_hr_user 1 0 0 0
16 access_attendance_action_reason_manager attendance.action.reason.manager model_attendance_action_reason hr_attendance.group_hr_attendance_manager 1 1 1 1
17 access_attendance_attendance attendance_attendance model_attendance_attendance base.group_user 1 0 0 0
18 access_attendance_attendance_hr attendance_attendance_hr model_attendance_attendance hr.group_hr_user 1 1 1 0
19 access_hr_attendance_wizard_hr hr_attendance_wizard_hr model_hr_attendance_wizard hr.group_hr_user 1 1 1 0
20 access_employee_attendance_report_hr employee_attendance_report_hr model_employee_attendance_report hr.group_hr_user 1 1 1 0
21 access_attendance_attendance_admin attendance_attendance_admin model_attendance_attendance base.group_system 1 1 1 1
22 access_hr_attendance_transaction_admin hr.attendance.transaction.admin model_hr_attendance_transaction base.group_system 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

View File

@ -0,0 +1,22 @@
@media (min-width: 768px){
.rtl .navbar-right{
float: left !important;
}
.rtl .navbar-right .dropdown .dropdown-menu{
right: auto !important;
left: 0 !important;
}
.rtl .navbar-left{
float: right !important;
}
.rtl .navbar-left .dropdown .dropdown-menu{
left: auto !important;
right: 0 !important;
}
.navbar-nav.navbar-right:last-child{
margin-left: auto;
}
.rtl .pull-left{
float: right !important;
}
}

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<menuitem id="menu_hr_attendance_configurations" name="Configuration"
parent="hr_attendance.menu_hr_attendance_root"
groups="hr_attendance.group_hr_attendance_user"
sequence="50"/>
<menuitem name="Lateness,Absence &amp;Overtime" id="employee_lateness_absence_overtime_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="hr_lateness_absence_overtime_action"
groups="hr_attendance.group_hr_attendance_user,hr_base.group_general_manager,hr_base.group_executive_manager"
sequence="4"/>
<menuitem name="Attendance Transactions" id="employee_attendance_transaction_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="hr_attendance_transaction_action"
sequence="3" groups="base.group_user"/>
<menuitem name="Lateness Reasons" id="employee_lateness_reasons_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="hr_lateness_reasons_action"
sequence="6"/>
<menuitem name=" Attendance Registration" id="hr_attendance_register_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="hr_attendance_register_action"
sequence="5"/>
<menuitem name="Attendance Configuration" id="resource_calendar_inherited_menu_item"
parent="menu_hr_attendance_configurations"
action="resource_calendar_inherited_action"
sequence="4"/>
<menuitem name="Attendance Reasons" id="attendance_action_reason_menu_item"
parent="menu_hr_attendance_configurations"
action="attendance_action_reason_action"
sequence="2"/>
<menuitem name="Attendances" id="attendance_custom_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="attendance_custom_action"
sequence="2"/>
<menuitem name="Get Missing Attendances" id="hr_attendance_wizard_menu_item"
parent="hr_attendance.menu_hr_attendance_root"
action="hr_attendance_wizard_action"
groups="hr_attendance.group_hr_attendance_user"
sequence="9"/>
<menuitem id="hr_attendance.menu_hr_attendance_settings" name="Setting"
parent="menu_hr_attendance_configurations" action="hr_attendance.action_hr_attendance_settings"
groups="hr_attendance.group_hr_attendance_manager"
sequence="1"/>
<record model="ir.ui.menu" id="hr_attendance.menu_hr_attendance_manage_attendances">
<field name="name">Record to hide menu</field>
<field name="groups_id" eval="[(6,0,[ref('make_invisible')])]"/>
</record>
<record model="ir.ui.menu" id="hr_attendance.menu_hr_attendance_report">
<field name="name">Record to hide menu</field>
<field name="groups_id" eval="[(6,0,[ref('make_invisible')])]"/>
</record>
<menuitem id="hr_attendance.menu_hr_attendance_root" name="Attendances" parent="hr.menu_hr_root" sequence="5"
groups="hr_attendance.group_hr_attendance"/>
</data>
</odoo>

View File

@ -0,0 +1,82 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="hr_attendance_register_action">
<field name="name">Attendance Register</field>
<field name="res_model">hr.attendance.register</field>
<field name="view_mode">tree,form</field>
</record>
<record id="hr_attendance_register_tree_view" model="ir.ui.view">
<field name="name">Attendance Register</field>
<field name="model">hr.attendance.register</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<group>
<field name="employee_id" string="Employee"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job"/>
<field name="action_type"/>
<field name="action_date"/>
<field name="register_date"/>
<field name="state"/>
</group>
</field>
</record>
<record model="ir.ui.view" id="hr_attendance_register_form_view">
<field name="name">Attendance Register</field>
<field name="model">hr.attendance.register</field>
<field name="arch" type="xml">
<form>
<header>
<button name="button_submit" string="Send" class="oe_highlight" type="object"
states="draft" groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="hr_manager" string="HR Manager" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="set_to_draft" string="Set To Draft" class="oe_highlight" type="object"
states="refused,hr_manager" groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar" statusbar_visible="draft,send,direct_manager,hr_manager,refused"/>
</header>
<sheet>
<group>
<group>
<field name="action_type" required="1" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="action_date" required="1" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="date" invisible="1"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
<group>
<field name="from_hr_depart" string="Another Employee" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee" domain="[('state','=','open')]"
attrs="{'readonly': ['|',('from_hr_depart','=',False),('state','!=','draft')],'required':True}"/>
<field name="department_id" string="Department" required="1" readonly="1"/>
<field name="job_id" string="Job" required="1" readonly="1"/>
<field name="register_date" required="1" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</group>
<separator string="Notes"/>
<field name="note_text" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"/>
</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"/>
</div>
</form>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,115 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="hr_lateness_absence_overtime_action">
<field name="name">Approval Of Attendance</field>
<field name="res_model">hr.attendance.report</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.view" id="employee_lateness_absense_overtime_form_view">
<field name="name">Approval Of Attendance</field>
<field name="model">hr.attendance.report</field>
<field name="arch" type="xml">
<form>
<header>
<button name="generate_report" string="Generate Report" class="oe_highlight" type="object"
states="draft" groups="hr.group_hr_user"/>
<button name="confirmed" string="HR Manager Approval" class="oe_highlight" type="object"
states="generated" groups="hr.group_hr_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="generated" groups="hr.group_hr_manager"
confirm="Are you sure to Refuse this Request?"/>
<button name="approved" string="Approved" class="oe_highlight" type="object"
states="confirmed" groups="hr_base.group_general_manager,hr_base.group_executive_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="confirmed" groups="hr_base.group_general_manager,hr_base.group_executive_manager"
confirm="Are you sure to Refuse this Request?"/>
<button name="set_to_draft" string="Set To Draft" class="oe_highlight" type="object"
states="approved,refused" groups="hr.group_hr_manager" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="date_from" string="Attendance Date From" required="True" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="deduct_date_from" string="Deduction Date From" required="True" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group>
<field name="date_to" string="Attendance Date To" required="True" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="deduct_date_to" string="Deduction Date To" required="True" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
</group>
<group>
<field name="calendar_ids" widget="many2many_tags" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<separator string="Report Details"/>
<field name="line_ids" nolabel="1" attrs="{'readonly':[('state','!=','generated')]}">
<tree editable="bottom">
<field name="employee_name" string="Employee Name" readonly="1"/>
<field name="delay" string="Delay" widget="float_time" readonly="1"/>
<field name="exists" string="Early Exist" widget="float_time" readonly="1"/>
<field name="extra_break_duration" string="Extra Break Duration" widget="float_time" readonly="1"/>
<field name="mission_by_days" string="Mission Hours" widget="float_time" readonly="1"/>
<field name="leave" string="Holiday Hours" widget="float_time" readonly="1"/>
<field name="absent" string="Absent Hours" widget="float_time" readonly="1"/>
<field name="additional_hours" string="Additional Hours" widget="float_time" readonly="1"/>
<field name="absent_days_by_hr" String='Absent Hours By HR' widget="float_time"/>
<field name="dummy_field" invisible="1" widget="float_time"/>
<field name="total_hours" String='Total Absence Hours' widget="float_time" readonly="1" force_save="1"/>
<field name="total_amount" String='Total Salary' readonly="1"/>
<field name="amount_per_hour" String='Amount Per Hour' readonly="1"/>
<field name="total_deduction" String='Total Deduction' readonly="1" force_save="1"/>
</tree>
<form>
<sheet>
<group>
<field name="employee_name" string="Employee Name"/>
<field name="delay" string="Delay" widget="float_time"/>
<field name="leave" string="Leave" widget="float_time"/>
<field name="exists" string="Early Exist" widget="float_time"/>
<field name="extra_break_duration" string="Extra Break Duration" widget="float_time"/>
<field name="mission_by_days" string="Missions By Days" widget="float_time"/>
<field name="absent" string="Absent" widget="float_time"/>
<field name="absent_days_by_hr" String='Absent Days By HR' widget="float_time"/>
<field name="total_hours" String='Total Working Hours' widget="float_time" force_save="1"/>
<field name="additional_hours" String='Additional Hours' widget="float_time" force_save="1"/>
<field name="total_amount" String='Total Salary'/>
<field name="amount_per_hour" String='Amount Per Hour'/>
<field name="total_deduction" String='Total Deduction' force_save="1"/>
<field name="dummy_field" invisible="1"/>
<field name="advantage_id" readonly="1" String='Deduction Employee'/>
</group>
</sheet>
</form>
</field>
</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"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="hr_lateness_attendance_overtime_tree_view">
<field name="name">Lateness Attendance OverTime</field>
<field name="model">hr.attendance.report</field>
<field name="arch" type="xml">
<tree decoration-success="state=='approved'" decoration-danger="state == 'refused'" decoration-info="state == 'draft'" >
<field name="date_from"/>
<field name="date_to"/>
<field name="state"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,112 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="hr_attendance_transaction_action">
<field name="name">Attendance Transactions</field>
<field name="res_model">hr.attendance.transaction</field>
<field name="view_mode">tree,form,calendar,graph</field>
</record>
<record id="attendance_transaction_tree_view" model="ir.ui.view">
<field name="name">Attendance Transactions</field>
<field name="model">hr.attendance.transaction</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree decoration-danger="is_absent == True" decoration-primary="approve_exit_out == True" decoration-muted="approve_lateness == True">
<field name="employee_number" string="Employee Number"/>
<field name="employee_id" string="Employee Name"/>
<field name="calendar_id"/>
<field name="date" string="Day"/>
<field name="sign_in" string="Sign In" widget="float_time"/>
<field name="sign_out" string="Sign Out" widget="float_time"/>
<field name="lateness" string="Lateness" widget="float_time"/>
<field name="early_exit" string="Early Exit" widget="float_time"/>
<!--field name="break_duration" string="Break" widget="float_time"/-->
<field name="office_hours" widget="float_time"/>
<field name="additional_hours" widget="float_time"/>
<field name="approve_exit_out" invisible="1"/>
<field name="approve_lateness" invisible="1"/>
<field name="is_absent"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="employee_attendance_transactions_form_view">
<field name="name">Attendance Transaction</field>
<field name="model">hr.attendance.transaction</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="employee_id" required="1" colspan="4" readonly="1"/>
<field name="employee_number" colspan="4" readonly="1" force_save="1" store="1"/>
<field name="company_id" groups="base.group_multi_company" colspan="4" readonly="1"/>
</group>
<group>
<group>
<field name="date" required="1"/>
<field name="calendar_id" />
<field name="attending_type" />
<field name="sequence" />
</group>
<group>
<field name="sign_in" widget="float_time" required="1"/>
<field name="sign_out" widget="float_time" required="1"/>
</group>
</group>
<group name="attendance">
<group>
<field name="approve_lateness" required="1" readonly="1"/>
<field name="lateness" string="Lateness" widget="float_time" readonly="1" force_save="1" store="1"/>
<field name="approve_exit_out" required="1" readonly="1"/>
<field name="early_exit" string="Early Exit" widget="float_time" required="1" readonly="1"/>
</group>
<group>
<field name="plan_hours" widget="float_time"/>
<field name="office_hours" widget="float_time"/>
<field name="official_hours" widget="float_time"/>
<field name="carried_hours" widget="float_time"/>
<field name="break_duration" widget="float_time"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_attendance_calendar" model="ir.ui.view">
<field name="name">hr.attendance.transaction.calendar</field>
<field name="model">hr.attendance.transaction</field>
<field eval="2" name="priority"/>
<field name="arch" type="xml">
<calendar date_start="date" string="Transaction" mode="month" color="employee_id">
<field name="employee_id"/>
<field name="sign_in" />
<field name="sign_out" />
</calendar>
</field>
</record>
<record id="view_transaction_graph" model="ir.ui.view">
<field name="name">hr.attendance.transaction.graph</field>
<field name="model">hr.attendance.transaction</field>
<field name="arch" type="xml">
<graph string="Attendance Transactions">
<field name="employee_id"/>
<field name="date"/>
</graph>
</field>
</record>
<!-- view_attendance_transaction_filter -->
<record id="view_attendance_transaction_filter" model="ir.ui.view">
<field name="name">Attendance Transaction</field>
<field name="model">hr.attendance.transaction</field>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="employee_id"/>
<field name="employee_number"/>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,370 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="resource_calendar_inherited_action">
<field name="name">Attendance Configuration</field>
<field name="res_model">resource.calendar</field>
<field name="view_mode">tree,form</field>
</record>
<record id="resource_calendar_inherited_form" model="ir.ui.view">
<field name="name">resource.calendar.inherited.form</field>
<field name="model">resource.calendar</field>
<field name="inherit_id" ref="resource.resource_calendar_form"/>
<field name="priority">100</field>
<field name="arch" type="xml">
<xpath expr="//sheet" position="replace">
<header>
<button name="act_confirm" string="Confirm" class="oe_highlight" type="object"
states="draft" groups="hr.group_hr_user"/>
<button name="act_update" string="Update" class="oe_highlight" type="object"
states="confirm" groups="hr.group_hr_user"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe.title">
<h>
<label for="name"/>
<field name="name"/>
</h>
</div>
<group col="4" colspan="2">
<group colspan="2">
<field name="working_days" required="1" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="working_hours" required="1" widget="float_time"
attrs="{'invisible':[('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="break_duration" required="1" widget="float_time"
attrs="{'invisible':['|', ('is_flexible','=',True), ('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="end_sign_in" required="1" widget="float_time"
attrs="{'invisible':[('is_flexible','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="number_of_flexi_days"
attrs="{'invisible':[('is_flexible','=',False)],
'required':[('is_flexible','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="total_flexible_hours" widget="float_time"
attrs="{'invisible':[('is_flexible','=',False)],
'required':[('is_flexible','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="deduction_rule" required="1"
domain="[('category_id.rule_type','=','deduction'),('special','=',True)]"/>
</group>
<group colspan="2">
<field name="is_full_day" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="is_flexible" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="noke" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="active"/>
</group>
<group string="Sign In Period" attrs="{'invisible':[('is_full_day','=',False)]}" colspan="2">
<field name="full_min_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],
'invisible':[('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="full_max_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],
'invisible':[('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
<group string="Sign Out Period" attrs="{'invisible':[('is_full_day','=',False)]}" colspan="2">
<field name="full_min_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],
'invisible':[('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="full_max_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],
'invisible':[('is_full_day','=',False)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
</group>
<!--<group col="4" colspan="4">
</group>
<group>
<group string="Sign In Period" attrs="{'invisible':[('is_full_day','=',False)]}">
<field name="full_min_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],'invisible':[('is_full_day','=',False)]}"/>
<field name="full_max_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],'invisible':[('is_full_day','=',False)]}"/>
</group>
<group string="Sign Out Period" attrs="{'invisible':[('is_full_day','=',False)]}">
<field name="full_min_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],'invisible':[('is_full_day','=',False)]}"/>
<field name="full_max_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',True)],'invisible':[('is_full_day','=',False)]}"/>
</group>
</group>
<group>
<group>
</group>
<group>
</group>
</group>-->
<notebook attrs="{'invisible':[('is_full_day','=',False)]}">
<page string="Day off">
<field name="full_day_off" attrs="{'readonly': [('state', '!=', 'draft')]}">
<tree editable="bottom">
<field name="name" required="1"/>
</tree>
</field>
</page>
<page string="Special Days" attrs="{'invisible':[('is_flexible','=',True)]}">
<field name="special_days" attrs="{'readonly': [('state', '!=', 'draft')]}">
<tree editable="bottom">
<field name="name" required="1"/>
<field name="start_sign_in" widget="float_time" required="1"/>
<field name="end_sign_in" widget="float_time" required="1"/>
<field name="start_sign_out" widget="float_time" required="1"/>
<field name="end_sign_out" widget="float_time" required="1"/>
<field name="working_hours" widget="float_time" required="1"/>
<field name="date_from" required="0"/>
<field name="date_to" required="0"/>
</tree>
</field>
</page>
<page string="Employees">
<field name="employee_ids" widget="many2many"
domain="[('contract_id.state', '=', 'program_directory')]"/>
</page>
<page string="Working Hours" invisible="1">
<field name="attendance_ids" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
</page>
<page string="Overtime Settings" name="over_time_full1">
<group>
<field name="work_days" string="Work Days overtime"/>
<field name="work_hour" string="Work Hours"/>
<field name="overtime_factor_daily"/>
<field name="overtime_factor_holiday"/>
<field name="max_overtime_hour"/>
</group>
</page>
<page string="Permission Settings" name="over_time_full">
<group>
<field name="permission_hours" string="Hours Per Day" widget="float_time" help="The Minimum Permission Hours Per Day"/>
<field name="permission_number" string="Hours Per Month" widget="float_time" help="The Maximum Permission Hours per Month"/>
</group>
</page>
</notebook>
<notebook attrs="{'invisible':[('is_full_day','=',True)]}">
<page string="Shift One">
<group>
<group string="Shift One Sign In Period"
attrs="{'invisible':[('is_full_day','=',True)]}">
<field name="shift_one_min_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="shift_one_max_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
<group string="Shift One Sign Out Period"
attrs="{'invisible':[('is_full_day','=',True)]}">
<field name="shift_one_min_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="shift_one_max_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
</group>
<group col="2" colspan="2">
<field name="shift_one_working_hours" required="1"
attrs="{'readonly': [('state', '!=', 'draft')]}"
widget="float_time"/>
<field name="shift_one_break_duration" required="1" widget="float_time"
attrs="{'invisible':[('is_flexible','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
</page>
<page string="Shift Two">
<group>
<group string="Shift Two Sign In Period"
attrs="{'invisible':[('is_full_day','=',True)]}">
<field name="shift_two_min_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="shift_two_max_sign_in" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
<group string="Shift Two Sign Out Period"
attrs="{'invisible':[('is_full_day','=',True)]}">
<field name="shift_two_min_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="shift_two_max_sign_out" widget="float_time"
attrs="{'required':[('is_full_day','=',False)],
'invisible':[('is_full_day','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
</group>
<group col="2" colspan="2">
<field name="shift_two_working_hours" required="1"
attrs="{'readonly': [('state', '!=', 'draft')]}"
widget="float_time"/>
<field name="shift_two_break_duration" required="1" widget="float_time"
attrs="{'invisible':[('is_flexible','=',True)],
'readonly': [('state', '!=', 'draft')]}"/>
</group>
</page>
<page string="Day off">
<field name="shift_day_off" attrs="{'readonly': [('state', '!=', 'draft')]}">
<tree editable="bottom">
<field name="name" required="1"/>
</tree>
</field>
</page>
<page string="Special Days" attrs="{'invisible':[('is_flexible','=',True)]}">
<field name="special_days_partcial" attrs="{'readonly': [('state', '!=', 'draft')]}">
<tree editable="bottom">
<field name="shift" required="1"/>
<field name="name" required="1"/>
<field name="start_sign_in" widget="float_time" required="1"/>
<field name="end_sign_in" widget="float_time" required="1"/>
<field name="start_sign_out" widget="float_time" required="1"/>
<field name="end_sign_out" widget="float_time" required="1"/>
<field name="working_hours" widget="float_time" required="1"/>
<field name="date_from"/>
<field name="date_to"/>
</tree>
</field>
</page>
<page string="Employees">
<field name="employee_ids"
domain="[('contract_id.state', '=', 'program_directory')]" widget="many2many"/>
</page>
<page string="Working Hours" invisible="1">
<field name="attendance_ids" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
</page>
<page string="Overtime And Permission" name="over_time_not_full">
<group>
<field name="permission_hours" string="Permission Hours" widget="float_time"/>
<field name="permission_number" string="Permission Number" widget="float_time"/>
<field name="work_days" string="Work Days overtime"/>
<field name="work_hour" string="Work Hours"/>
<field name="overtime_factor_daily"/>
<field name="overtime_factor_holiday"/>
<field name="max_overtime_hour"/>
</group>
</page>
</notebook>
</sheet>
</xpath>
</field>
</record>
<record model="ir.actions.act_window" id="attendance_custom_action">
<field name="name">Employee Attendances</field>
<field name="res_model">attendance.attendance</field>
<field name="view_mode">tree,form</field>
</record>
<record id="attendance_custom_form" model="ir.ui.view">
<field name="name">attendance.custom.form</field>
<field name="model">attendance.attendance</field>
<field name="arch" type="xml">
<form string="Employee attendances">
<sheet>
<group>
<field name="employee_id" readonly="1" force_save="1"/>
<field name="employee_number" readonly="1" force_save="1" store="1"/>
<field name="name" required="1" readonly="1" force_save="1"/>
<field name="action" readonly="1" force_save="1"/>
<field name="action_type" readonly="1" force_save="1"/>
<field name="action_reason" readonly="1" force_save="1"/>
<field name="action_date" readonly="1"/>
<field name="taken" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="attendance_custom_tree" model="ir.ui.view">
<field name="name">attendance.custom.tree</field>
<field name="model">attendance.attendance</field>
<field name="arch" type="xml">
<tree>
<field name="employee_number"/>
<field name="employee_id"/>
<field name="name" required="1"/>
<field name="action"/>
<field name="action_type"/>
</tree>
</field>
</record>
<record id="attendance_view_filter" model="ir.ui.view">
<field name="name">attendance_view_filter</field>
<field name="model">attendance.attendance</field>
<field name="arch" type="xml">
<search string="Attendance Search">
<field name="employee_id"/>
<field name="employee_number"/>
<separator/>
<!-- <filter string="My Attendances" domain="[('employee_id.user_id', '=', uid)]"/>-->
<group expand="0" string="Group By">
<filter name="employee" string="Employee" context="{'group_by':'employee_id'}"/>
<separator/>
</group>
</search>
</field>
</record>
<!-- view_attendance_filter >
<record id="view_attendance_filter" model="ir.ui.view">
<field name="name">Attendance Attendance</field>
<field name="model">attendance.attendance</field>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="employee_id"/>
<field name="employee_number"/>
</field>
</record-->
<record id="attendance_action_reason_form" model="ir.ui.view">
<field name="name">attendance.action.reason.form</field>
<field name="model">attendance.action.reason</field>
<field name="arch" type="xml">
<form>
<sheet>
<group col="4" colspan="4">
<field name="name" required="1"/>
<field name="type"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="attendance_action_reason_tree" model="ir.ui.view">
<field name="name">attendance.action.reason.tree</field>
<field name="model">attendance.action.reason</field>
<field name="arch" type="xml">
<tree string="Attendance Reasons">
<field name="name"/>
<field name="type"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="attendance_action_reason_action">
<field name="name">Attendance Reasons</field>
<field name="res_model">attendance.action.reason</field>
<field name="view_mode">tree,form</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="hr_attendance_action_hr_employee" model="ir.actions.act_window">
<field name="name">Attendances Action</field>
<field name="res_model">attendance.attendance</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_employee_id': active_id, 'default_employee_id': active_id}</field>
<field name="help" type="html">
<p>No attendance records to display.</p>
</field>
</record>
<record id="view_employee_attendance_form_inherit" model="ir.ui.view">
<field name="name">hr.employee</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="priority">11</field>
<field name="groups_id" eval="[(4,ref('hr_attendance.group_hr_attendance_user'))]"/>
<field name="arch" type="xml">
<xpath expr="//button[1]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<div name="button_box" position="inside">
<button name="%(hr_attendance_action_hr_employee)d"
class="oe_stat_button"
type="action">
<div class="o_stat_info">
<div id="oe_hr_attendance_status" title="Attendance Green" class="fa fa-fw fa-user o_button_icon oe_hr_attendance_status_green" attrs="{'invisible': [('attendance_state', '=', 'checked_out')]}"/>
<div id="oe_hr_attendance_status" title="Attendance Red" class="fa fa-fw fa-user o_button_icon oe_hr_attendance_status_red" attrs="{'invisible': ['|',('attendance_state', '=', 'checked_in'),('attendance_state', '=',False)]}"/>
<span class="o_stat_text">Attendance</span>
</div>
</button>
</div>
<xpath expr="//page[@name='hr_settings']/group/group[2]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//notebook//page[@name='hr_settings']//group[@name='active_group']" position="inside">
<field name="barcode" string="Fingerprint Number" attrs="{'readonly':[('state','!=','draft')]}"/>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,83 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="hr_lateness_reasons_action">
<field name="name">lateness Reasons</field>
<field name="res_model">hr.reasons.lateness</field>
<field name="view_mode">tree,form</field>
</record>
<record id="hr_lateness_tree_view" model="ir.ui.view">
<field name="name">lateness reason</field>
<field name="model">hr.reasons.lateness</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<group>
<field name="employee_id" string="Employee"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job"/>
<field name="request_date" string="Request Date"/>
<field name="latest_date" string="lateness Date"/>
<field name="reasons" string="Reasons"/>
<field name="state" string="State"/>
</group>
</field>
</record>
<record model="ir.ui.view" id="employee_lateness_reasons_form_view">
<field name="name">Lateness Reasons</field>
<field name="model">hr.reasons.lateness</field>
<field name="arch" type="xml">
<form>
<header>
<button name="button_submit" string="Send" class="oe_highlight" type="object"
states="draft" groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="hr_manager" string="HR Manager" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="set_to_draft" string="Set To Draft" class="oe_highlight" type="object"
states="refused,hr_manager" groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,send,direct_manager,hr_manager,refused"/>
</header>
<sheet>
<group>
<group>
<field name="request_date" string="Request Date" readonly="1" />
<field name="latest_date" string="lateness Date" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="reasons" string="Reasons" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
<group>
<field name="from_hr_depart" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee"
attrs="{'readonly': ['|',('from_hr_depart','=',False),('state','!=','draft')],'required':True}"/>
<field name="department_id" string="Department" required="1" readonly="1"/>
<field name="job_id" string="Job" required="1" readonly="1"/>
</group>
</group>
</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"/>
</div>
</form>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import attendance_wizard
from . import attendances_report_wiz

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from odoo import models, fields
from datetime import datetime, timedelta
class HrAttendanceWizard(models.TransientModel):
_name = 'hr.attendance.wizard'
date_from = fields.Datetime(string='Date From')
date_to = fields.Datetime(string='Date To')
get_attendance_from = fields.Selection(selection=[('finger_print', 'Finger Print'),
('manual', 'Manual')], string='Get Attendances From')
def generate_missing_attendance(self):
transactions = self.env['hr.attendance.transaction']
if self.get_attendance_from == 'manual':
start_date = datetime.strptime(str(self.date_from), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(self.date_to), "%Y-%m-%d %H:%M:%S")
delta = end_date - start_date
for i in range(delta.days + 1):
day = start_date + timedelta(days=i)
transactions.process_attendance_scheduler_queue(day)
else:
if self.env['ir.module.module'].sudo().search([('state', '=', 'installed'),
('name', '=', 'to_attendance_device')]):
self.env['attendance.wizard'].cron_sync_attendance()

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="attendance_wizard_form_view" model="ir.ui.view">
<field name="name">Get Missing Attendances</field>
<field name="model">hr.attendance.wizard</field>
<field name="arch" type="xml">
<form>
<group colspan="4" col="4">
<field name="get_attendance_from" required="1" colspan="4"/>
<field name="date_from" attrs="{'required':[('get_attendance_from', '!=', 'finger_print')],
'invisible':[('get_attendance_from', '=', 'finger_print')]}"/>
<field name="date_to" attrs="{'required':[('get_attendance_from', '!=', 'finger_print')],
'invisible':[('get_attendance_from', '=', 'finger_print')]}"/>
</group>
<footer>
<button name="generate_missing_attendance" string="Create or Update" type="object"
class="btn-primary"/>
<button string="Cancel" class="btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="hr_attendance_wizard_action">
<field name="name">Get Missing Attendances</field>
<field name="res_model">hr.attendance.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="employee_attendance_report_wizard_view" model="ir.ui.view">
<field name="name">Employee Attendance Report</field>
<field name="model">employee.attendance.report</field>
<field name="arch" type="xml">
<form string="Employee Attendance Report">
<sheet>
<group>
<group>
<field name="resource_calender_id"/>
<field name="from_date"/>
<field name="type"/>
</group>
<group>
<field name="to_date"/>
<!-- <field name="employee_ids" widget="many2many_tags"/>-->
</group>
</group>
<notebook>
<page string="Employees" >
<field name="employee_ids" nolabel="1">
<tree string="Employees" editable="bottom">
<field name="name"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<footer>
<button string="Print Report" type="object" name="print_report" class="oe_highlight"/>
or
<button string="Print Excel Report" type="object" name="print_excel_report" class="oe_highlight"/>
or
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="employee_attendance_report_wizard_action" model="ir.actions.act_window">
<field name="name">Employee Attendance Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.attendance.report</field>
<field name="view_mode">form</field>
<field name="view_id" ref="employee_attendance_report_wizard_view"/>
<field name="target">new</field>
</record>
<menuitem name="Attendance Reports" id="parent_attendance_report_employee"
parent="hr_attendance.menu_hr_attendance_root" sequence="41"/>
<menuitem name="Attendance Reports" id="attendance_report_emp_menu"
parent="attendances.parent_attendance_report_employee"
action="employee_attendance_report_wizard_action"/>
</data>
</odoo>

View File

@ -0,0 +1,270 @@
# -*- coding: utf-8 -*-
import collections
import datetime
from odoo import api, fields, models, _
class AttendancesReport(models.TransientModel):
_name = "employee.attendance.report"
_description = "Employee Attendance Report"
from_date = fields.Date(string='From Date', required=True)
to_date = fields.Date(string='To Date', required=True)
employee_ids = fields.Many2many(comodel_name='hr.employee', string='Employees')
resource_calender_id = fields.Many2one(comodel_name='resource.calendar', string='Employee work record')
type = fields.Selection(selection=[('late', 'Late and Early exit'), ('absent', 'Absent'), ('employee', 'Employee')],
required=True,
default='late', string='Type')
def print_report(self):
data = {
'ids': self.ids,
'model': self._name,
'form': {
'resource_calender_id': self.resource_calender_id.id,
'from_date': self.from_date,
'to_date': self.to_date,
'employee_ids': self.employee_ids.ids,
'type': self.type,
},
}
return self.env.ref('attendances.general_attendance_action_report').report_action(self, data=data)
def print_excel_report(self):
data = {
'ids': self.ids,
'model': self._name,
'form': {
'resource_calender_id': self.resource_calender_id.id,
'from_date': self.from_date,
'to_date': self.to_date,
'employee_ids': self.employee_ids.ids,
'type': self.type,
},
}
return self.env.ref('attendances.general_attendance_action_xls').report_action(self, data=data, config=False)
class ReportAttendancePublic(models.AbstractModel):
_name = 'report.attendances.general_attendances_report_temp'
_description = "General Attendances Report"
def get_value(self, data):
type = data['form']['type']
employee_ids = data['form']['employee_ids']
resource_calender_id = data['form']['resource_calender_id']
from_date = data['form']['from_date']
to_date = data['form']['to_date']
domain = [('date', '>=', from_date), ('date', '<=', to_date)]
data = []
final_dic = {}
key_list = []
total_dic = {}
mykey = []
resource = self.env['resource.calendar'].browse(resource_calender_id)
if resource:
if resource.employee_ids:
for emp in resource.employee_ids:
employee_ids.append(emp.id)
# if resource_calender_id:
# contract_ids = self.env['hr.contract'].search([('state', '=', 'program_directory'), ('resource_calendar_id', '=', resource_calender_id)])
# for con in contract_ids:
# employee_ids.append(con.employee_id.id)
# print(">>>>>>>>>>>>>>>>>>>>>>>employeesemployees",employees)
if employee_ids:
last_employee_ids = list(set(employee_ids))
domain.append(('employee_id', 'in', last_employee_ids))
attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)
employees = attendance_transaction_ids.mapped('employee_id.name')
if type == 'late':
for resource in attendance_transaction_ids:
data.append({
'date': resource.date,
'sig_in': resource.sign_in,
'sig_out': resource.sign_out,
'lateness': resource.lateness,
'early_exit': resource.early_exit,
'employee_id': resource.employee_id,
'employee_name': resource.employee_id.name,
})
for emp in employees:
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
total_lateness = sum(list_cat.mapped('lateness'))
total_lateness = str(datetime.timedelta(minutes=total_lateness))
total_early_exit = sum(list_cat.mapped('early_exit'))
total_early_exit = str(datetime.timedelta(minutes=total_early_exit))
list_absent = attendance_transaction_ids.filtered(
lambda r: r.employee_id.name == emp and r.is_absent == True)
total_absent = len(list_absent)
list_not_log_in = attendance_transaction_ids.filtered(
lambda r: r.employee_id.name == emp and r.sign_in == 0.0)
total_not_sig_in = len(list_not_log_in)
list_not_log_out = attendance_transaction_ids.filtered(
lambda r: r.employee_id.name == emp and r.sign_out == 0.0)
total_not_sig_out = len(list_not_log_out)
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit,
'total_absent': total_absent, 'total_not_sig_in': total_not_sig_in,
'total_not_sig_out': total_not_sig_out}
grouped = collections.defaultdict(list)
for item in data:
grouped[item['employee_name']].append(item)
for key, value in grouped.items():
final_dic[key] = list(value)
key_list.append(key)
mykey = list(dict.fromkeys(key_list))
return final_dic, mykey, total_dic
elif type == 'absent':
for resource in attendance_transaction_ids.filtered(lambda r: r.is_absent == True):
data.append({
'date': resource.date,
'employee_name': resource.employee_id.name,
'employee_id_department_id_name': resource.employee_id.department_id.name,
'day': datetime.datetime.strptime(str(resource.date), '%Y-%m-%d').date().strftime('%A'),
})
grouped = collections.defaultdict(list)
for item in data:
grouped[item['employee_id_department_id_name']].append(item)
for key, value in grouped.items():
final_dic[key] = list(value)
key_list.append(key)
mykey = list(dict.fromkeys(key_list))
return final_dic, mykey, ''
elif type == 'employee':
for emp in employees:
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
total_lateness = sum(list_cat.mapped('lateness'))
total_lateness = str(datetime.timedelta(minutes=total_lateness))
total_early_exit = sum(list_cat.mapped('early_exit'))
total_early_exit = str(datetime.timedelta(minutes=total_early_exit))
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit}
key_list.append(emp)
mykey = list(dict.fromkeys(key_list))
return '', mykey, total_dic
@api.model
def _get_report_values(self, docids, data=None):
final_dic, mykey, total = self.get_value(data)
start_date = data['form']['from_date']
end_date = data['form']['to_date']
type = data['form']['type']
return {
'doc_ids': data['ids'],
'doc_model': data['model'],
'date_start': start_date,
'date_end': end_date,
'type': type,
'data': final_dic,
'mykey': mykey,
'total': total,
}
class AttendancesReportXls(models.AbstractModel):
_name = 'report.attendances.general_attendance_xls'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, data, datas):
x = self.env['report.attendances.general_attendances_report_temp']
final_dic, mykey, total = ReportAttendancePublic.get_value(x, data)
start_date = data['form']['from_date']
end_date = data['form']['to_date']
type = data['form']['type']
sheet = workbook.add_worksheet(U'Holiday Report')
sheet.right_to_left()
format2 = workbook.add_format(
{'font_size': 10, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
'bold': True})
format2.set_align('center')
format2.set_align('vcenter')
if type == 'late':
sheet.merge_range('C3:G3', _("Late and Early Exit Report"), format2)
sheet.merge_range('B4:C4', _("From date"), format2)
sheet.merge_range('F4:G4', _("To date"), format2)
sheet.write(3, 3, str(start_date)[0:10], format2)
sheet.write(3, 7, str(end_date)[0:10], format2)
row = 8
for key in mykey:
n = 1
size = len(final_dic[key])
tot_size = len(total[key])
sheet.write(row - 2, n, _('Name'), format2)
sheet.write(row, n, _('date'), format2)
sheet.write(row, n + 1, _('Sign in'), format2)
sheet.write(row, n + 2, _('Sign out'), format2)
sheet.write(row, n + 3, _('lateness'), format2)
sheet.write(row, n + 4, _('Early Exit'), format2)
sheet.write(row, n + 5, _('Notes'), format2)
data_row = row + 1
for line in final_dic[key]:
sheet.write(row - 2, n + 1, line['employee_name'], format2)
sheet.write(data_row, n, line['date'], format2)
sheet.write(data_row, n + 1, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_in']) * 60, 60)),
format2)
sheet.write(data_row, n + 2, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_out']) * 60, 60)),
format2)
sheet.write(data_row, n + 3,
'{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['lateness']) * 60, 60)), format2)
sheet.write(data_row, n + 4,
'{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['early_exit']) * 60, 60)), format2)
sheet.write(data_row, n + 5, (' '), format2)
data_row += 1
sheet.write(data_row, n, _('Total lateness'), format2)
sheet.write(data_row, n + 1, str(total[key]['total_lateness']), format2)
sheet.write(data_row, n + 2, _('Total Early Exit'), format2)
sheet.write(data_row, n + 3, str(total[key]['total_early_exit']), format2)
sheet.write(data_row, n + 4, _('Total Absent'), format2)
sheet.write(data_row, n + 5, str(total[key]['total_absent']), format2)
size -= 2
sheet.write(data_row + 1, n, _('Total Not Sign In'), format2)
sheet.write(data_row + 1, n + 1, str(total[key]['total_not_sig_in']), format2)
sheet.write(data_row + 1, n + 2, _('Total Not Sign Out'), format2)
sheet.write(data_row + 1, n + 3, total[key]['total_not_sig_out'], format2)
n += 1
row += size + 3 + tot_size
elif type == 'absent':
sheet.merge_range('C3:G3', _("Absent Report"), format2)
sheet.merge_range('C4:G4', _("All Employee - Details"), format2)
sheet.merge_range('B5:C5', _("From date"), format2)
sheet.merge_range('F5:G5', _("To date"), format2)
sheet.write(4, 3, str(start_date)[0:10], format2)
sheet.write(4, 7, str(end_date)[0:10], format2)
row = 8
for key in mykey:
n = 1
size = len(final_dic[key])
sheet.write(row - 2, n, _('Department'), format2)
sheet.write(row, n, _('Employee Name'), format2)
sheet.write(row, n + 1, _('Day'), format2)
sheet.write(row, n + 2, _('date'), format2)
sheet.write(row, n + 3, _('Notes'), format2)
data_row = row + 1
for line in final_dic[key]:
sheet.write(row - 2, n + 1, line['employee_id_department_id_name'], format2)
sheet.write(data_row, n, line['employee_name'], format2)
sheet.write(data_row, n + 1, line['day'], format2)
sheet.write(data_row, n + 2, line['date'], format2)
sheet.write(data_row, n + 3, (' '), format2)
data_row += 1
n += 1
row += size + 3
elif type == 'employee':
sheet.merge_range('C3:G3', _("Employee Attendance Report"), format2)
sheet.merge_range('B4:C4', _("From date"), format2)
sheet.merge_range('F4:G4', _("To date"), format2)
sheet.write(3, 3, str(start_date)[0:10], format2)
sheet.write(3, 7, str(end_date)[0:10], format2)
row = 8
for key in mykey:
n = 1
size = len(total[key])
sheet.write(row, n, _('Employee Name'), format2)
sheet.write(row, n + 1, _('Total of Lateness '), format2)
sheet.write(row, n + 2, _('Total of Early Exit'), format2)
data_row = row + 1
sheet.write(data_row, n, key, format2)
sheet.write(data_row, n + 1, total[key]['total_lateness'], format2)
sheet.write(data_row, n + 2, total[key]['total_early_exit'], format2)
data_row += 1
n += 1
row += size + 1

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# LCT, Life Connection Technology
# Copyright (C) 2019-2020 LCT
#
##############################################################################
from . import models
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# LCT, Life Connection Technology
# Copyright (C) 2011-2012 LCT
#
##############################################################################
{
'name' : 'Base Custom',
'category': 'HR-Odex',
'version' : '1.0',
'author': 'Expert Co. Ltd.' ,
'website': 'http://exp-sa.com',
'summary': 'Solving defulat groups for newly created users',
'description' : """Add the following features: 1-Prevent granting defulat groups for newly created users """,
'depends' : ['base','web','mail'],
'data': [ ],
'auto_install': False,
'installable': True,
'application': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-# -*- coding: utf-8 -*-
##############################################################################
#
# LCT, Life Connection Technology
# Copyright (C) 2011-2012 LCT
#
##############################################################################
from . import res_users

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# LCT, Life Connection Technology
# Copyright (C) 2011-2012 LCT
#
##############################################################################
from odoo import api, fields, models, _
class ResUsers(models.Model):
_inherit = 'res.users'
def _default_groups_custom(self):
"""
pervents newly created user from holding all managers groups.
"""
default_user = self.env.ref('base.group_user', raise_if_not_found=False)
return default_user
groups_id = fields.Many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', string='Groups', default =_default_groups_custom)

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,22 @@
@media (min-width: 768px){
.rtl .navbar-right{
float: left !important;
}
.rtl .navbar-right .dropdown .dropdown-menu{
right: auto !important;
left: 0 !important;
}
.rtl .navbar-left{
float: right !important;
}
.rtl .navbar-left .dropdown .dropdown-menu{
left: auto !important;
right: 0 !important;
}
.navbar-nav.navbar-right:last-child{
margin-left: auto;
}
.rtl .pull-left{
float: right !important;
}
}

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import report

View File

@ -0,0 +1,46 @@
{
'name': 'Employee Requests',
'category': 'Odex25-HR/Odex25-HR',
'summary': 'HR Management Employee Requests and self service',
'version': '1.0',
'sequence': 4,
'website': 'http://exp-sa.com',
'license': 'GPL-3',
'author': 'Expert Co. Ltd.',
'depends': ['base', 'account', 'hr_loans_salary_advance', 'exp_payroll_custom',
'attendances'],
'data': [
'security/employee_requests_security.xml',
'security/ir.model.access.csv',
'views/employee_effective_form.xml',
'views/employee_overtime_request.xml',
'views/hr_clearance_form.xml',
'views/hr_personal_permission.xml',
'views/customize_hr_employee.xml',
'views/employee_department_jobs_view.xml',
'views/other_request.xml',
'views/attendance_view.xml',
'report/employee_clearance_report/employee_clearance_form_reports.xml',
'report/employee_clearance_report/employee_clearance_form_template1.xml',
'report/employee_clearance_report/employee_clearannce_detailes_template.xml',
'report/clearance_employee_report_template.xml',
'report/employee_department_jobs_template.xml',
'report/employee_appointment_report_template.xml',
'report/disclaimer_certificate.xml',
'report/report_employee_identify.xml',
'report/report_employee_identify_2.xml',
'report/report_employee_identify_3.xml',
'report/salary_confirmation.xml',
# menu items
'views/employee_request_menu.xml',
],
# 'qweb': ['static/src/xml/base_template.xml'],
'installable': True,
'application': True,
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from . import employee_effective_form
from . import employee_overtime_request
from . import hr_clearance_form
from . import document_directory
from . import hr_personal_permission
from . import house_allowance_advance
from . import employee
from . import employee_department_jobs
from . import attendance
from . import other_request

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from odoo import models, fields
class Transactions(models.Model):
_inherit = 'hr.attendance.transaction'
personal_permission_id = fields.Many2one('hr.personal.permission', string='Permission Request')
approve_personal_permission = fields.Boolean(string='Permission')
total_permission_hours = fields.Float()

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from odoo import models, fields
class DocumentDirectory(models.Model):
_name = 'document.directory'
_description = 'Document Directory'
name = fields.Char(string='Directory')

View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class DegreeMedical(models.Model):
_name = "degree.medical.issuance"
_description = "Medical Insurance Degree"
# degree_medical_insurance
name = fields.Char(translate=True)
company_insurance = fields.Char()
class HrEmployee(models.Model):
_inherit = "hr.employee"
# passport fields to private information page
date_issuance_passport = fields.Date()
expiration_date_passport = fields.Date()
place_issuance_passport = fields.Char()
own_license = fields.Boolean()
# Accommodation and medical insurance page
###Residence
residency_number = fields.Char(string="Insurances Number")
date_issuance_residence = fields.Date()
expiration_date_residence = fields.Date()
place_issuance_residence = fields.Char()
first_entry_into_saudi_arabia = fields.Date()
number_of_visa = fields.Integer()
###Guaranty
on_company_guarantee = fields.Boolean(default=True)
validity_transfer_sponsorship = fields.Date()
###Medical Insurance
medical_insurance = fields.Boolean(default=True)
degree_medical_insurance = fields.Many2one('degree.medical.issuance')
medical_insurance_number = fields.Char()
date_of_expiry = fields.Date(related='copy_examination_file.expiry_date', readonly=True)
copy_examination_file = fields.Many2one('hr.employee.document',
domain=[('document_type', '=', 'medical_Examination')])
filename = fields.Char()
# Payment method
payment_method = fields.Selection(selection=[("cash", _("Cash")), ("bank", _("Bank"))])
date_of_employment = fields.Date()
length_of_service = fields.Integer()
@api.onchange('country_id','saudi_number','iqama_number')
def _get_medical_insurance_number(self):
for item in self:
if item.country_id.code == "SA":
item.medical_insurance_number = item.saudi_number.saudi_id
else:
item.medical_insurance_number = item.iqama_number.iqama_id

View File

@ -0,0 +1,194 @@
# -*- coding: utf-8 -*-
import datetime
from dateutil import relativedelta
from odoo import api, fields, models, _, exceptions
class EmployeeDepartmentJobs(models.Model):
_name = 'employee.department.jobs'
_rec_name = 'employee_id'
_description = 'Employee Department and Jobs'
_inherit = ['mail.thread', 'mail.activity.mixin']
date = fields.Date()
comment = fields.Text()
state = fields.Selection(selection=[('draft', _('Draft')),
('confirm', _('Department Manager')),
('hr_officer', _('HR Officer')),
('confirm2', _('Department Manager2')),
('hr_manager', _('HR Manager')),
('approved', _('Approved')), ('refused', _('Refused'))],
default='draft', tracking=True)
promotion_type = fields.Selection(
selection=[('department', _('Department')), ('job', _('Job')), ('both', _('Both'))], tracking=True)
# relational fields
employee_id = fields.Many2one(comodel_name="hr.employee", tracking=True, domain=[('state', '=', 'open')])
# old_department_id = fields.Many2one(comodel_name='hr.department', related='employee_id.department_id')
old_department_2_id = fields.Many2one(comodel_name='hr.department')
# old_job_id = fields.Many2one(comodel_name='hr.job', related='employee_id.job_id')
old_job_2_id = fields.Many2one(comodel_name='hr.job')
new_department_id = fields.Many2one(comodel_name='hr.department')
new_job_id = fields.Many2one(comodel_name='hr.job')
new_manager_id = fields.Many2one(comodel_name='hr.employee', related='new_department_id.manager_id')
old_manager_id = fields.Many2one(comodel_name='hr.employee', related='old_department_2_id.manager_id')
old_job_date = fields.Date(string='Old Job Date', readonly=True)
last_record = fields.Boolean(string='Is Last Record?', default=True)
service_year = fields.Integer(compute='_compute_duration', store=True)
service_month = fields.Integer(compute='_compute_duration', store=True)
service_day = fields.Integer(compute='_compute_duration', store=True)
company_id = fields.Many2one(related='employee_id.company_id', string="Company")
@api.onchange('new_department_id', 'new_job_id')
def not_reused_same_dep_job(self):
for item in self:
if item.new_department_id.department_type == 'unit':
item.new_manager_id = item.new_department_id.parent_id.manager_id
else:
item.new_manager_id = item.new_department_id.manager_id
if item.employee_id:
if item.old_department_2_id.id == item.new_department_id.id:
raise exceptions.Warning(_('You Can Not Choose The Same Department Name'))
if item.old_job_2_id.id == item.new_job_id.id:
raise exceptions.Warning(_('You Can Not Choose The Same Job Name'))
if item.new_job_id:
if item.new_job_id.no_of_recruitment < 1:
raise exceptions.Warning(_('There Is No Vacancy For This Job Name %s')% item.new_job_id.name)
# store department and job
@api.onchange('employee_id')
def store_level_group_and_degree_values(self):
for item in self:
if item.sudo().employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(
_('You can not Request Change Department or job The Employee have Not First Hiring Date'))
item.old_department_2_id = item.employee_id.department_id
item.old_job_2_id = item.employee_id.job_id
item.old_manager_id = item.old_department_2_id.manager_id
item.old_job_date = item.employee_id.joining_date
@api.depends('date', 'old_job_date')
def _compute_duration(self):
for item in self:
if item.sudo().employee_id.first_hiring_date and item.date:
if item.date <= item.sudo().employee_id.first_hiring_date:
raise exceptions.Warning(_('Sorry, Procedure Date Must Be After Employee Hiring Date'))
if item.old_job_date and item.date:
date_start = datetime.datetime.strptime(str(item.old_job_date), '%Y-%m-%d').date()
date_end = datetime.datetime.strptime(str(item.date), '%Y-%m-%d').date()
item.service_year = relativedelta.relativedelta(date_end, date_start).years
item.service_month = relativedelta.relativedelta(date_end, date_start).months
item.service_day = relativedelta.relativedelta(date_end, date_start).days
if item.date <= item.old_job_date and item.promotion_type != 'department':
raise exceptions.Warning(_('Sorry, Procedure Date Must Be After Old Job Date'))
def confirm(self):
for item in self:
previous_record = self.search([('employee_id', '=', item.employee_id.id),
('id', '!=', item.id),
('state', '=', 'approved'),
('promotion_type', '=', item.promotion_type),
('last_record', '=', True)
], order='date desc', limit=1)
if previous_record:
previous_record.last_record = False
self.state = 'confirm'
def hr_officer(self):
for rec in self:
if rec.promotion_type == 'job':
rec.state = 'confirm2'
else:
rec.state = 'hr_officer'
def confirm2(self):
for rec in self:
if rec.promotion_type != 'job':
if rec.new_manager_id and rec.new_manager_id.user_id.id != rec.env.user.id:
raise exceptions.Warning(
_('Sorry, It Must Be Approved By The %s Manager') % rec.new_manager_id.name)
else:
if rec.old_manager_id.user_id.id != rec.env.user.id:
raise exceptions.Warning(
_('Sorry, It Must Be Approved By The %s Manager') % rec.old_manager_id.name)
self.state = 'confirm2'
def hr_manager(self):
self.state = 'hr_manager'
def approved(self):
for item in self:
if item.promotion_type == 'department':
if item.new_department_id:
item.employee_id.write({
'department_id': item.new_department_id.id
})
item.employee_id._onchange_department()
elif item.promotion_type == 'job':
if item.new_job_id:
item.employee_id.write({
'job_id': item.new_job_id.id,
'joining_date': item.date
})
elif item.promotion_type == 'both':
if item.new_job_id and item.new_department_id:
item.employee_id.write({
'department_id': item.new_department_id.id,
'job_id': item.new_job_id.id,
'joining_date': item.date
})
item.employee_id._onchange_department()
self.state = 'approved'
def refused(self):
self.state = 'refused'
def draft(self):
for item in self:
if not item.last_record:
raise exceptions.Warning(_('The record Cannot be Set To Draft Because It Is Not Last Record'))
previous_record = self.search([('employee_id', '=', item.employee_id.id),
('id', '!=', item.id),
('state', '=', 'approved'),
('promotion_type', '=', item.promotion_type),
('last_record', '=', False)], order='date desc', limit=1)
if item.promotion_type == 'department':
if item.new_department_id:
item.employee_id.write({
'department_id': item.old_department_2_id.id
})
item.employee_id._onchange_department()
elif item.promotion_type == 'job':
if item.new_job_id:
item.employee_id.write({
'job_id': item.old_job_2_id.id,
'joining_date': item.old_job_date
})
elif item.promotion_type == 'both':
if item.new_job_id and item.new_department_id:
item.employee_id.write({
'department_id': item.old_department_2_id.id,
'job_id': item.old_job_2_id.id,
'joining_date': item.old_job_date
})
item.employee_id._onchange_department()
if previous_record:
previous_record.last_record = True
self.state = 'draft'
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(EmployeeDepartmentJobs, self).unlink()
def print_report(self):
return self.env.ref('employee_requests.employee_department_jobs_action_report').report_action(self)

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _, exceptions
class EmployeeEffectiveForm(models.Model):
_name = 'employee.effective.form'
_rec_name = 'employee_id'
_inherit = ['mail.thread', 'mail.activity.mixin']
from_hr = fields.Boolean()
contract_id = fields.Many2one(related='employee_id.contract_id', readonly=True, string='Contract')
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
employee_salary = fields.Float(related='employee_id.contract_id.salary', readonly=True, tracking=True)
remarks = fields.Text()
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
effective_form_type = fields.Selection([('first_tim_job', _('First Time Job')),
('return_from_leave', _('Return From Leave'))], default="first_tim_job")
effective_form_date = fields.Date(tracking=True)
state = fields.Selection(
[('draft', _('Draft')), ('submit', _('Submit')), ('direct_manager', _('Direct Manager')),
('hr_manager', _('Hr Manager')), ('done', _('Done')),
('refused', _('Refused'))],
default="draft", tracking=True)
contract_start = fields.Date(related='contract_id.date_start', readonly=True,
string='Contract Start Date')
company_id = fields.Many2one('res.company',string="Company", default=lambda self: self.env.user.company_id)
@api.onchange('employee_id')
def get_hiring_date(self):
for rec in self:
if rec.employee_id:
rec.effective_form_date = rec.contract_start
@api.constrains('employee_id', 'effective_form_date')
def once_request(self):
for i in self:
employee_id = self.env['employee.effective.form'].search([('id', '!=', i.id),('employee_id', '=', i.employee_id.id), ('state', '=', 'done')], limit=1)
if employee_id:
raise exceptions.Warning(_('Sorry, Not possible to request a effective Form more than once'))
if i.contract_start:
if i.effective_form_date < i.contract_start:
raise exceptions.Warning(_('Sorry, The First Hiring Date must be after the Contract Start Date'))
if i.employee_id.contract_id.state != 'program_directory':
raise exceptions.Warning(_('Sorry, The Employee Contract Must Be Approved Before Hiring Date'))
if i.employee_id.state != 'open':
raise exceptions.Warning(_('Sorry, The Employee Record Must Be Approved Before Hiring Date'))
def draft_state(self):
for item in self:
if item.effective_form_type == 'first_tim_job' and item.state == 'done':
item.employee_id.sudo().write({'first_hiring_date': False, 'joining_date': False})
item.employee_id.contract_id.sudo().write({'hiring_date': False})
item.state = "draft"
def submit(self):
'''for item in self:
mail_content = "Hello I'm", item.employee_id.name, " request Need to ", item.effective_form_type,"Please approved thanks."
main_content = {
'subject': _('Request Effective-%s Employee %s') % (item.effective_form_type, item.employee_id.name),
'author_id': self.env.user.partner_id.id,
'body_html': mail_content,
'email_to': item.department_id.email_manager,
}
self.env['mail.mail'].create(main_content).send()'''
self.once_request()
self.state = "submit"
def direct_manager(self):
self.state = "direct_manager"
def hr_manager(self):
self.state = "hr_manager"
def done(self):
for item in self:
if item.effective_form_type == 'first_tim_job':
item.employee_id.sudo().write({'first_hiring_date': item.effective_form_date,
'joining_date': item.effective_form_date})
item.employee_id.contract_id.sudo().write({'hiring_date': item.effective_form_date})
else:
return False
self.state = "done"
def refused(self):
self.state = "refused"
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(EmployeeEffectiveForm, self).unlink()
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False

View File

@ -0,0 +1,427 @@
# -*- coding: utf-8 -*-
from __future__ import division
from datetime import datetime
from odoo import models, fields, api, _, exceptions
from odoo.exceptions import UserError
# import logging
class employee_overtime_request(models.Model):
_name = 'employee.overtime.request'
_rec_name = 'request_date'
_inherit = ['mail.thread', 'mail.activity.mixin']
request_date = fields.Date(default=lambda self: fields.Date.today())
reason = fields.Text()
date_to = fields.Date()
date_from = fields.Date()
transfer_type = fields.Selection([('accounting', 'Accounting'), ('payroll', 'Payroll')], default='payroll')
overtime_plase = fields.Selection([('inside', 'Inside'), ('outside', 'Outside')])
state = fields.Selection(
[('draft', _('Draft')),
('submit', _('Waiting Direct Manager')),
('direct_manager', _('Waiting Department Manager')),
('financial_manager', _('Wait HR Department')),
('hr_aaproval', _('Wait Approval')),
('executive_office', _('Wait Transfer')),
('validated', _('Transferred')),
('refused', _('Refused'))], default="draft", tracking=True)
# Relation fields
account_id = fields.Many2one(comodel_name='account.account', string='Account')
journal_id = fields.Many2one(comodel_name='account.journal', string='Payment Method')
benefits_discounts = fields.Many2one(comodel_name='hr.salary.rule', string='Benefits/Discounts',
domain=[('rules_type', '=', 'overtime')])
line_ids_over_time = fields.One2many(comodel_name='line.ids.over.time', inverse_name='employee_over_time_id',
tracking=True)
department_id = fields.Many2one('hr.department')
employee_id = fields.Many2one('hr.employee', 'Responsible', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
exception = fields.Boolean(string="Exception Hours", default=False,
help='Exceeding The Limit Of Overtime Hours Per Month')
company_id = fields.Many2one('res.company',string="Company", default=lambda self: self.env.user.company_id)
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
@api.onchange('employee_id')
def get_department_id(self):
if self.employee_id:
self.department_id = self.employee_id.department_id.id
@api.onchange('transfer_type', 'account_id', 'journal_id', 'line_ids_over_time')
def onchange_transfer_type(self):
if self.transfer_type == 'payroll':
self.account_id = False
self.journal_id = False
for line in self.line_ids_over_time:
line.account_id = False
line.journal_id = False
if self.transfer_type == 'accounting':
for line in self.line_ids_over_time:
if self.state == 'hr_aaproval':
if not line.account_id:
line.account_id = self.account_id
if not line.journal_id:
line.journal_id = self.journal_id
else:
line.account_id = False
line.journal_id = False
@api.onchange('account_id')
def onchange_account_id(self):
for line in self.line_ids_over_time:
line.account_id = self.account_id
@api.onchange('journal_id')
def onchange_journal_id(self):
for line in self.line_ids_over_time:
line.journal_id = self.journal_id
def re_draft(self):
# when redraft cancel the created account move
if self.transfer_type == 'payroll':
for record in self.line_ids_over_time:
record.advantage_id.draft()
record.advantage_id.unlink()
self.state = 'draft'
if self.transfer_type == 'accounting':
if self.line_ids_over_time[0].move_id:
move_id_not_draft = False
for line in self.line_ids_over_time:
if line.move_id.state == 'posted':
move_id_not_draft_name = line.move_id.name
move_id_not_draft = True
if move_id_not_draft:
raise exceptions.Warning(_(
'You can not cancel account move "%s" in state not draft') % move_id_not_draft_name)
else:
for record in self.line_ids_over_time:
# record.move_id.write({'state': 'canceled'})
record.move_id.unlink()
record.write({
'move_id': False
})
record.account_id = False
record.journal_id = False
self.write({'state': 'draft'})
self.account_id = False
self.journal_id = False
else:
self.write({
'state': 'draft',
'account_id': False,
'journal_id': False
})
for record in self.line_ids_over_time:
record.write({
'move_id': False,
'account_id': False,
'journal_id': False
})
def submit(self):
if not self.line_ids_over_time:
raise exceptions.Warning(_('Sorry, Can Not Request without The Employees'))
self.chick_not_mission()
self.state = "submit"
def direct_manager(self):
self.chick_not_mission()
self.state = "direct_manager"
def financial_manager(self):
self.chick_not_mission()
self.state = "financial_manager"
def hr_aaproval(self):
self.chick_not_mission()
if self.exception == True:
self.state = "hr_aaproval"
else:
self.state = "executive_office"
def executive_office(self):
self.chick_not_mission()
self.state = "executive_office"
def validated(self):
if self.transfer_type == 'accounting':
for item in self:
for record in item.line_ids_over_time:
debit_line_vals = {
'name': record.employee_id.name,
'debit': record.price_hour,
'account_id': record.account_id.id,
'partner_id': record.employee_id.user_id.partner_id.id
}
credit_line_vals = {
'name': record.employee_id.name,
'credit': record.price_hour,
'account_id': record.journal_id.default_account_id.id,
'partner_id': record.employee_id.user_id.partner_id.id
}
move = record.env['account.move'].create({
'state': 'draft',
'journal_id': record.journal_id.id,
'date': item.request_date,
'ref': record.employee_id.name,
'line_ids': [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
})
record.move_id = move.id
self.state = "validated"
if self.transfer_type == 'payroll':
# last_day_of_current_month = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])
# first_day_of_current_month = date.today().replace(day=1)
for item in self:
for record in item.line_ids_over_time:
if record.employee_id.contract_id:
advantage_arc = record.env['contract.advantage'].create({
'benefits_discounts': item.benefits_discounts.id,
'type': 'customize',
'date_from': item.date_from,
'date_to': item.date_to,
'amount': record.price_hour,
'over_time_id': True,
'employee_id': record.employee_id.id,
'contract_advantage_id': record.employee_id.contract_id.id,
'out_rule': True,
'state': 'confirm',
'comments': item.reason})
record.advantage_id = advantage_arc.id
else:
raise exceptions.Warning(_('Employee "%s" has no contract Please create contract to add '
'line to advantages') % record.employee_id.name)
self.state = "validated"
def refused(self):
self.state = "refused"
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
i.line_ids_over_time.unlink()
return super(employee_overtime_request, self).unlink()
@api.onchange('line_ids_over_time.employee_id', 'date_from', 'date_to')
def chick_not_mission(self):
for rec in self:
Module = self.env['ir.module.module'].sudo()
modules_mission = Module.search([('state', '=', 'installed'), ('name', '=', 'exp_official_mission')])
if modules_mission:
if rec.date_to and rec.date_from:
if rec.date_to < rec.date_from:
raise exceptions.Warning(_('Date Form Must Be Less than Date To'))
for line in rec.line_ids_over_time:
clause_1 = ['&', ('official_mission_id.date_from', '<=', rec.date_from),
('official_mission_id.date_to', '>=', rec.date_from)]
clause_2 = ['&', ('official_mission_id.date_from', '<=', rec.date_to),
('official_mission_id.date_to', '>=', rec.date_to)]
clause_3 = ['&', ('official_mission_id.date_from', '>=', rec.date_from),
('official_mission_id.date_to', '<=', rec.date_to)]
mission = self.env['hr.official.mission.employee'].search(
[('employee_id', '=', line.employee_id.id), ('official_mission_id.state', '!=', 'refused'),
('official_mission_id.mission_type.related_with_financial', '=', True),
('official_mission_id.mission_type.work_state', '=', 'legation'),
'|', '|'] + clause_1 + clause_2 + clause_3)
if mission:
raise exceptions.Warning(_('Sorry The Employee %s Actually Has Legation '
'Amount For this Period') % line.employee_id.name)
# TOOO DOOO
@api.onchange('overtime_plase', 'date_from', 'date_to', 'exception')
def chick_hours_calenders(self):
self.line_ids_over_time.chick_hours_calender()
class HrEmployeeOverTime(models.Model):
_name = 'line.ids.over.time'
_rec_name = 'employee_id'
over_time_workdays_hours = fields.Float(string="workdays hours", tracking=True)
over_time_vacation_hours = fields.Float(string="Vacation days hours", tracking=True)
daily_hourly_rate = fields.Float(string='Daily Hourly Rate', compute='get_over_time_amount', store=True)
holiday_hourly_rate = fields.Float(string='Holiday Hourly Rate', compute='get_over_time_amount', store=True)
price_hour = fields.Float(string='Overtime Amount', compute='get_over_time_amount', store=True)
# Relational fields
account_id = fields.Many2one('account.account')
journal_id = fields.Many2one('account.journal', string='Payment Method', domain=[('type', 'in', ('bank', 'cash'))])
move_id = fields.Many2one('account.move')
employee_id = fields.Many2one('hr.employee', string='Employee', required=True)
employee_over_time_id = fields.Many2one('employee.overtime.request', string='Employee')
calculate_from_total = fields.Boolean(string="Calculate From Total")
transfer_type = fields.Selection(related='employee_over_time_id.transfer_type')
advantage_id = fields.Many2one(comodel_name='contract.advantage', string='Allowance Employee')
max_hours = fields.Float(compute='get_max_remain_hours', string="Max Hours", store=True)
remaining_hours = fields.Float(compute='get_max_remain_hours', string="Remaining Hours", store=True)
exception = fields.Boolean(string="Exception", default=False)
overtime_plase = fields.Selection(related='employee_over_time_id.overtime_plase', store=True,
string="Overtime Plase")
state = fields.Selection(related='employee_over_time_id.state', store=True, string="State")
@api.onchange('overtime_plase', 'over_time_workdays_hours', 'over_time_vacation_hours', 'employee_id', 'exception')
def chick_hours_calender(self):
for rec in self:
overtime_day_hour = 0
overtime_holi_hour = 0
# day_hour=0.0
# holiday_hour=0.0
if rec.employee_id:
if not rec.employee_id.first_hiring_date:
raise exceptions.Warning(
_('You can not Request Overtime The Employee %s have Not First Hiring Date') % rec.employee_id.name)
if rec.overtime_plase == 'inside' and rec.employee_id:
attendance_transaction = self.env['hr.attendance.transaction'].search(
[('employee_id', '=', rec.employee_id.id),
('date', '>=', rec.employee_over_time_id.date_from),
('date', '<=', rec.employee_over_time_id.date_to)])
for tran in attendance_transaction:
if tran.additional_hours > 0 and not tran.public_holiday:
overtime_day_hour += tran.additional_hours
if tran.public_holiday:
overtime_holi_hour += tran.office_hours
if rec.over_time_workdays_hours > overtime_day_hour and not rec.exception:
raise exceptions.Warning(
_('The Overtime Workdays Employee %s Exceeded The Attendance workdays '
'Hours') % rec.employee_id.name)
if rec.over_time_vacation_hours > overtime_holi_hour and not rec.exception:
raise exceptions.Warning(
_('The Overtime Publice Holiday Employee %s Exceeded The Attendance Public '
'Holiday Hours') % rec.employee_id.name)
# dynamic domain on employee_id
# Select employee once in Over Time Line
@api.onchange('employee_id')
def get_emplyee_id_domain(self):
# Check if employee selected once
if self.employee_over_time_id.department_id:
# for dep in self.official_mission_id.department_id:
employee_id = self.env['hr.employee'].search(
[('department_id', '=', self.employee_over_time_id.department_id.id), ('state', '=', 'open')]).ids
if employee_id:
for line in self.employee_over_time_id.line_ids_over_time:
if line.employee_id:
if line.employee_id.id in employee_id:
employee_id.remove(line.employee_id.id)
return {'domain': {'employee_id': [('id', 'in', employee_id)]}}
else:
employee_id = self.env['hr.employee'].search([('state', '=', 'open')]).ids
if employee_id:
for line in self.employee_over_time_id.line_ids_over_time:
if line.employee_id:
if line.employee_id.id in employee_id:
employee_id.remove(line.employee_id.id)
return {'domain': {'employee_id': [('id', 'in', employee_id)]}}
@api.model
def default_get(self, fields):
res = super(HrEmployeeOverTime, self).default_get(fields)
if self._context.get('account_id') and self._context.get('journal_id'):
res['account_id'] = self._context.get('account_id')
res['journal_id'] = self._context.get('journal_id')
return res
@api.depends('employee_id.contract_id', 'over_time_workdays_hours', 'over_time_vacation_hours', 'employee_id',
'calculate_from_total')
def get_over_time_amount(self):
for line in self:
contract_id = line.employee_id.contract_id
if contract_id.working_hours:
wage_daily = contract_id.total_allowance + (
contract_id.salary * contract_id.working_hours.overtime_factor_daily)
# 1/2 Basic salary + total Salaey
wage_holiday = contract_id.total_allowance + (
contract_id.salary * contract_id.working_hours.overtime_factor_holiday)
# 1 Basic salary + total Salaey
total_hours = contract_id.working_hours.work_days * contract_id.working_hours.work_hour
# 240 per month
if total_hours != 0:
price_hour_daily = wage_daily / total_hours
price_hour_holiday = wage_holiday / total_hours
# if line.over_time_workdays_hours > 0 or line.over_time_vacation_hours > 0:
if line.employee_id:
line.daily_hourly_rate = price_hour_daily
o_t_a_d = price_hour_daily * line.over_time_workdays_hours
line.holiday_hourly_rate = price_hour_holiday
o_t_a_v = price_hour_holiday * line.over_time_vacation_hours
line.price_hour = o_t_a_d + o_t_a_v
emp_total_hours = line.over_time_workdays_hours + line.over_time_vacation_hours
# if emp_total_hours > contract_id.working_hours.max_overtime_hour:
# raise exceptions.Warning(_('The Number Of Overtime Hours For The Employee %s Is Greater
# Max Hours per Month')% line.employee_id.name)
else:
raise exceptions.Warning(_('The Number Of Overtime Hours And Days is Missing'))
# else:
# line.daily_hourly_rate = 0
# line.holiday_hourly_rate = 0
#
# line.price_hour = 0
@api.depends('employee_id.contract_id', 'employee_id', 'employee_over_time_id.date_from',
'employee_over_time_id.date_to','over_time_workdays_hours')
def get_max_remain_hours(self):
for line in self:
contract_id = line.employee_id.contract_id
if contract_id.working_hours:
line.max_hours = contract_id.working_hours.max_overtime_hour
if line.employee_over_time_id.date_to and line.employee_over_time_id.date_from:
month_current_from = datetime.strptime(str(line.employee_over_time_id.date_from),
'%Y-%m-%d').strftime('%m')
year_current_from = datetime.strptime(str(line.employee_over_time_id.date_from),
'%Y-%m-%d').strftime('%y')
month_current_to = datetime.strptime(str(line.employee_over_time_id.date_to),
'%Y-%m-%d').strftime('%m')
year_current_to = datetime.strptime(str(line.employee_over_time_id.date_to),
'%Y-%m-%d').strftime('%y')
if month_current_from != month_current_to or year_current_from != year_current_to:
raise exceptions.Warning(
_('Sorry, The overtime period Must be During the same Month for the Year'))
overtime_ids = self.search(
[('employee_id', '=', line.employee_id.id), ('employee_over_time_id.state', '!=', 'refused')])
total_hours = 0.0
remaining_hours = line.max_hours
for rec in overtime_ids:
month_previous = datetime.strptime(str(rec.employee_over_time_id.date_from),
'%Y-%m-%d').strftime('%m')
year_previous = datetime.strptime(str(rec.employee_over_time_id.date_from),
'%Y-%m-%d').strftime('%y')
if month_current_from == month_previous and year_current_from == year_previous:
total_hours += rec.over_time_workdays_hours + rec.over_time_vacation_hours
remaining_hours = line.max_hours - total_hours
line.remaining_hours = remaining_hours
if remaining_hours < 0 and line.exception == False:
raise UserError(
_('The Number Of Overtime Hours For The Employee %s Is Greater Max Hours per '
'Month') % line.employee_id.name)
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrEmployeeOverTime, self).unlink()

View File

@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _, exceptions
from datetime import datetime
class HouseAllowanceAdvance(models.Model):
_name = 'house.allowance.advance'
_rec_name = 'employee_id'
from_hr_department = fields.Boolean()
amount = fields.Float()
date = fields.Date()
start_date = fields.Date()
duration = fields.Float(compute='get_Days_no')
state = fields.Selection(
[('draft', _('Draft')), ('send', _('Send')), ('hr_special_Approval', _('HR Specialist Approval')),
('hr_manager_approved', _('HR Manager Approved')),
('financial_manager', _('Financial Manager Approval')),
('approve_manager', _('Approve Manager')), ('refused', _('Refused'))],
default="draft")
# relational fields
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
contract_id = fields.Many2one(comodel_name='hr.contract')
account_move_id = fields.Many2one(comodel_name='hr.account.moves', string='Move')
house_allowance_advance_line_ids = fields.One2many('house.allowance.advance.line', 'amount_id')
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id())
@api.depends('start_date', 'date')
def get_Days_no(self):
for item in self:
if item.start_date and item.date:
start_date_value = datetime.strptime(str(item.start_date), "%Y-%m-%d")
end_date = datetime.strptime(str(item.date), "%Y-%m-%d")
if start_date_value > end_date:
raise exceptions.Warning(_('End Date must be greater than Start Date'))
elif start_date_value < end_date:
days = (end_date - start_date_value).days
item.duration = days
else:
item.duration = 0.0
else:
item.duration = 0.0
def draft_state(self):
self.state = "draft"
def send(self):
self.state = "send"
def hr_special_Approval(self):
self.state = "hr_special_Approval"
def financial_manager(self):
self.state = "financial_manager"
def hr_manager_approved(self):
self.state = "hr_manager_approved"
def approve_manager(self):
self.state = "approve_manager"
def refused(self):
self.state = "refused"
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HouseAllowanceAdvance, self).unlink()
class HouseAllowanceAdvanceLine(models.Model):
_name = 'house.allowance.advance.line'
date = fields.Date()
# relational fields
amount_id = fields.Many2one(comodel_name='house.allowance.advance', string='Amount')

View File

@ -0,0 +1,166 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _, exceptions
class HrClearanceForm(models.Model):
_name = 'hr.clearance.form'
_rec_name = 'employee_id'
_inherit = ['mail.thread', 'mail.activity.mixin']
from_hr_department = fields.Boolean()
# employee_id = fields.Many2one(comodel_name='hr.employee')
date = fields.Date(default=lambda self: fields.Date.today())
date_deliver_work = fields.Date()
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
clearance_type = fields.Selection(selection=[("vacation", _("Vacation Clearance")),
("final", _("Final Clearance"))], default='final')
work_delivered = fields.Text()
super_mg = fields.Selection(selection=[("approve", _("Approve")),
("refuse", _("Refuse"))], default='approve')
super_refuse_cause = fields.Text(default='/')
direct_mg = fields.Selection(selection=[("approve", _("Approve")),
("refuse", _("Refuse"))], default='approve')
direct_refuse_cause = fields.Text(default='/')
hr_mg = fields.Selection(selection=[("approve", _("Approve")),
("refuse", _("Refuse"))], default='approve')
hr_refuse_cause = fields.Text(default='/')
it_mg = fields.Selection(selection=[("approve", _("Approve")),
("refuse", _("Refuse"))], default='approve')
it_refuse_cause = fields.Text(default='/')
state = fields.Selection(selection=[("draft", _("Draft")),
("submit", _("Submitted")),
("direct_manager", _("Direct Manager")),
('info_system', _('IT Department')),
('admin_manager', _('Admin Affairs')),
("wait", _("Finance Approvals")),
("done", _("HR Manager")),
("refuse", _("Refuse"))], default='draft', tracking=True)
bank_attachment_id = fields.Many2many('ir.attachment', 'clearance_form_rel', 'bank_id', 'attach_id',
string="Attachment",
help='You can attach the copy of your document', copy=False)
bank_comments = fields.Text()
company_id = fields.Many2one('res.company',string="Company", default=lambda self: self.env.user.company_id)
@api.constrains('employee_id')
def chick_hiring_date(self):
for item in self:
if item.employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(_('You can not Request Clearance The Employee have Not First Hiring Date'))
def draft(self):
self.state = "draft"
def submit(self):
# Check if exp_custody_petty_cash module is installed
Module = self.env['ir.module.module'].sudo()
emp_modules = Module.search([('state', '=', 'installed'), ('name', '=', 'exp_employee_custody')])
petty_cash_modules = Module.search([('state', '=', 'installed'), ('name', '=', 'hr_expense_petty_cash')])
if emp_modules:
# Check if employee has Employee Custody not in state Return done
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', self.employee_id.id), ('state', 'in', ['submit', 'direct', 'admin', 'approve'])])
if len(employee_custody) > 0:
raise exceptions.Warning(
_(
'You can not Employee Clearance %s employee custody not in state Return Done for %s please '
'reconcile it') % (
self.employee_id.name, len(employee_custody)))
if petty_cash_modules:
# Check if employee has Employee Petty Cash Payment not in state Return done
employee_petty_cash_payment = self.env['petty.cash'].search(
[('partner_id', '=', self.employee_id.user_id.partner_id.id),
('state', 'in', ['submit', 'direct', 'fm', 'ceo', 'accepted', 'validate'])])
if len(employee_petty_cash_payment) > 0:
raise exceptions.Warning(
_('You can not Employee Clearance %s employee petty cash payment not in state Return Done for %s '
'please reconcile it') % (
self.employee_id.name, len(employee_petty_cash_payment)))
'''for item in self:
mail_content = "Hello I'm", item.employee_id.name, " request to Clearance Of ", item.clearance_type,"Please approved thanks."
main_content = {
'subject': _('Request clearance-%s Employee %s') % (item.clearance_type, item.employee_id.name),
'author_id': self.env.user.partner_id.id,
'body_html': mail_content,
'email_to': item.department_id.email_manager,
}
self.env['mail.mail'].create(main_content).send()'''
self.state = "submit"
def direct_manager(self):
# Check if exp_custody_petty_cash module is installed
Module = self.env['ir.module.module'].sudo()
emp_modules = Module.search([('state', '=', 'installed'), ('name', '=', 'exp_employee_custody')])
petty_cash_modules = Module.search([('state', '=', 'installed'), ('name', '=', 'hr_expense_petty_cash')])
modules = Module.search([('state', '=', 'installed'), ('name', '=', 'exp_custody_petty_cash')])
if emp_modules:
# Check if employee has Employee Custody not in state Return done
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', self.employee_id.id), ('state', 'in', ['submit', 'direct', 'admin', 'approve'])])
if len(employee_custody) > 0:
raise exceptions.Warning(
_('You can not Employee Clearance "%s" employee custody not in state Return '
'Done for "%s" please reconcile it') % (len(employee_custody), self.employee_id.name))
if petty_cash_modules:
# Check if employee has Employee Petty Cash Payment not in state Return done
employee_petty_cash_payment = self.env['petty.cash'].search(
[('partner_id', '=', self.employee_id.user_id.partner_id.id),
('state', 'in', ['submit', 'direct', 'fm', 'ceo', 'accepted', 'validate'])])
if len(employee_petty_cash_payment) > 0:
raise exceptions.Warning(
_('You can not Employee Clearance "%s" employee petty cash payment not in state Return '
'Done for "%s" please reconcile it') % (
len(employee_petty_cash_payment), self.employee_id.name))
self.state = "direct_manager"
def info_system(self):
self.state = "info_system"
def admin_manager(self):
self.state = "admin_manager"
def wait(self):
for item in self:
if not item.bank_attachment_id and item.clearance_type != 'vacation':
raise exceptions.Warning(_('The Clearance to be completed after the Bank Clearance Attachment'))
self.state = "wait"
def done(self):
if not self.bank_attachment_id:
raise exceptions.Warning(_('The Clearance to be completed after the Bank Clearance Attachment'))
self.employee_id.write({'is_calender': True})
self.state = "done"
def refuse(self):
self.state = "refuse"
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrClearanceForm, self).unlink()

View File

@ -0,0 +1,301 @@
# -*- coding: utf-8 -*-
from calendar import monthrange
import time
from datetime import datetime
from odoo import models, fields, api, _, exceptions
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from datetime import timedelta
from odoo.exceptions import ValidationError
class HrPersonalPermission(models.Model):
_name = 'hr.personal.permission'
_rec_name = 'employee_id'
_inherit = ['mail.thread', 'mail.activity.mixin']
from_hr_department = fields.Boolean()
date = fields.Date(default=lambda self: fields.Date.today())
date_from = fields.Datetime()
date_to = fields.Datetime()
duration = fields.Float(compute='get_duration_no' ,store=True)
employee_contract_id = fields.Many2one(comodel_name='hr.contract.type')
balance = fields.Float(related='employee_id.contract_id.working_hours.permission_hours')
permission_number = fields.Float(store=True, readonly=True,
help='The Remaining Number of Hours permission This Month')
early_exit = fields.Boolean()
mission_purpose = fields.Text()
employee_no = fields.Char(related='employee_id.emp_no', readonly=True)
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
refuse_cause = fields.Text()
attach_ids = fields.One2many('ir.attachment', 'personal_permission_id')
approved_by = fields.Many2one(comodel_name='res.users')
refused_by = fields.Many2one(comodel_name='res.users')
employee_id = fields.Many2one('hr.employee', 'Employee Id', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
state = fields.Selection(
[('draft', _('Draft')), ('send', _('Waiting Direct Manager')), ('direct_manager', _('Wait HR Department')),
('approve', _('Approved'))
, ('refused', _('Refused'))], default="draft", tracking=True)
type_exit = fields.Selection(
[('early_exit', _('Early Exit')), ('late entry', _('Late Entry')), ('during work', _('During Work'))],
default="early_exit")
company_id = fields.Many2one('res.company',string="Company", default=lambda self: self.env.user.company_id)
@api.model
def create(self, vals):
new_record = super(HrPersonalPermission, self).create(vals)
for item in new_record:
if item.date_from and item.date_to and item.employee_id:
calendar = item.employee_id.resource_calendar_id
start_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
hour_star = start_date.hour + 3
hour_end = end_date.hour + 3
if calendar.is_full_day:
cal_hour_star = calendar.full_min_sign_in
cal_hour_end = calendar.full_max_sign_out
if cal_hour_end <= hour_end or hour_end < cal_hour_star:
raise exceptions.Warning(_('Sorry, Permission Must Be within The Attendance Hours'))
return new_record
@api.onchange('date_from')
def _get_duration_hours(self):
for item in self:
if item.date_from:
permission_hour = item.employee_id.resource_calendar_id.permission_hours
start_date_hour = datetime.strptime(str(item.date_from), "%Y-%m-%d %H:%M:%S")
end_date_hour = start_date_hour + timedelta(hours=permission_hour)
item.date_to = end_date_hour
@api.depends('date_from', 'date_to')
def get_duration_no(self):
for item in self:
if item.date_from and item.date_to:
start_date_value = datetime.strptime(str(item.date_from), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
if start_date_value <= end_date:
days = (end_date - start_date_value).days
seconds_diff = (end_date - start_date_value).seconds
item.duration = (days * 24) + seconds_diff / 3600
# function permission_number_decrement and _get_date_constrains replaced in new module hr permission holiday to fix
# singleton issue and change constrain
@api.onchange('date_to', 'date_from', 'employee_id')
def permission_number_decrement(self):
for item in self:
if item.employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(
_('You can not Request Permission The Employee have Not First Hiring Date'))
if item.date_to:
current_date = datetime.strptime(str(item.date_to), DEFAULT_SERVER_DATETIME_FORMAT)
current_month = datetime.strptime(str(item.date_to), DEFAULT_SERVER_DATETIME_FORMAT).month
date_from = current_date.strftime('%Y-{0}-01'.format(current_month))
date_to = current_date.strftime('%Y-{0}-01'.format(current_month + 1))
if current_month == 12:
date_to = current_date.strftime('%Y-{0}-31'.format(current_month))
number_of_per = item.employee_id.contract_id.working_hours.permission_number
employee_permissions = self.search([
('employee_id', '=', item.employee_id.id),
('state', '=', 'approve'),
('date_from', '>=', date_from),
('date_to', '<=', date_to)])
all_perission = 0
for rec in employee_permissions:
all_perission += rec.duration
if rec.date_to and item.date_to:
permission_date1 = datetime.strptime(rec.date_to,
DEFAULT_SERVER_DATETIME_FORMAT).date()
date_to_value1 = datetime.strptime(item.date_to, DEFAULT_SERVER_DATETIME_FORMAT).date()
if permission_date1 == date_to_value1:
raise exceptions.Warning(
_('Sorry You Have Used All Your Permission In This Day you have one permission per a Day'))
if number_of_per > all_perission:
item.permission_number = round(number_of_per - all_perission, 2)
else:
raise ValidationError(_('Sorry You Have Used All Your Permission Hours In This Month'))
def check_holiday_mission(self):
for rec in self:
if rec.date_from and rec.date_to:
clause_1, clause_2, clause_3 = rec.get_domain(rec.date_from, rec.date_to)
clause_final = [('id', '!=', rec.id), ('employee_id', '=', rec.employee_id.id),
('state', '!=', 'refuse'),
'|', '|'] + clause_1 + clause_2 + clause_3
record = rec.search(clause_final)
if record:
raise exceptions.Warning(_('Sorry The Employee Actually in Permission For this Period'))
Module = self.env['ir.module.module'].sudo()
modules = Module.search([('state', '=', 'installed'), ('name', '=', 'exp_official_mission')])
modules_holidays = Module.search([('state', '=', 'installed'), ('name', '=', 'hr_holidays_public')])
date_to = str(datetime.strptime(str(rec.date_to), DEFAULT_SERVER_DATETIME_FORMAT).date())
date_from = str(datetime.strptime(str(rec.date_from), DEFAULT_SERVER_DATETIME_FORMAT).date())
clause_1, clause_2, clause_3 = rec.get_domain(date_from, date_to)
if modules_holidays:
clause_final = [('employee_id', '=', rec.employee_id.id), ('state', '!=', 'refuse'),
('type', '=', 'remove'),
'|', '|'] + clause_1 + clause_2 + clause_3
holidays = self.env['hr.holidays'].search(clause_final)
if holidays:
raise exceptions.Warning(_('Sorry The Employee %s Actually On %s For this Period') %
(rec.employee_id.name, holidays.holiday_status_id.name))
if modules:
date_to = datetime.strptime(str(self.date_to), DEFAULT_SERVER_DATETIME_FORMAT)
date_from = datetime.strptime(str(self.date_from), DEFAULT_SERVER_DATETIME_FORMAT)
if date_to and date_from:
delta = timedelta(days=1)
while date_from <= date_to:
clause_1, clause_2, clause_3 = self.get_mission_domain(date_from, date_from)
clause_final = [('employee_id', '=', rec.employee_id.id),
('official_mission_id.state', '!=', 'refused'),
('date_from', '<=', str(date_from.date())),
('date_to', '>=', str(date_from.date())),
'|', '|'] + clause_1 + clause_2 + clause_3
mission_dfrm = self.env['hr.official.mission.employee'].search(clause_final)
if mission_dfrm:
raise exceptions.Warning(_('Sorry The Employee %s Actually'
' On Mission/Training For this Period') % rec.employee_id.name)
date_from += delta
def get_mission_domain(self, date_from, date_to):
date_from_time = (date_from + timedelta(hours=3)).time()
date_to_time = (date_to + timedelta(hours=3)).time()
hour_from = date_from_time.hour + date_from_time.minute / 60.0
hour_to = date_to_time.hour + date_to_time.minute / 60.0
clause_1 = ['&', ('hour_from', '<=', hour_from), ('hour_to', '>=', hour_from)]
clause_2 = ['&', ('hour_from', '<=', hour_to), ('hour_to', '>=', hour_to)]
clause_3 = ['&', ('hour_from', '>=', hour_from), ('hour_to', '<=', hour_to)]
return clause_1, clause_2, clause_3
def get_domain(self, date_from, date_to):
clause_1 = ['&', ('date_to', '<=', date_to), ('date_to', '>=', date_from)]
clause_2 = ['&', ('date_from', '<=', date_to), ('date_from', '>=', date_from)]
clause_3 = ['&', ('date_from', '<=', date_from), ('date_to', '>=', date_to)]
return clause_1, clause_2, clause_3
@api.constrains('date_from', 'date_to')
def _get_date_constrains(self):
for item in self:
item.check_holiday_mission()
current_month = (datetime.utcnow() + timedelta(hours=3)).date().month
current_year = (datetime.utcnow() + timedelta(hours=3)).date().year
month_len = monthrange(current_year, current_month)[1]
number_of_per = item.employee_id.contract_id.working_hours.permission_number
number_of_durations = item.employee_id.contract_id.working_hours.permission_hours
this_month_permission = self.search([('employee_id', '=', item.employee_id.id), ('state', '=', 'approve'),
('date_from', '>=', time.strftime('%Y-{0}-1'.format(current_month))),
('date_to', '<=',
time.strftime('%Y-{0}-{1}'.format(current_month, month_len)))])
if item.date_to:
current_date = datetime.strptime(str(item.date_to), DEFAULT_SERVER_DATETIME_FORMAT)
current_month = datetime.strptime(str(item.date_to), DEFAULT_SERVER_DATETIME_FORMAT).month
date_from = current_date.strftime('%Y-{0}-01'.format(current_month))
date_to = current_date.strftime('%Y-{0}-01'.format(current_month + 1))
if current_month == 12:
date_to = current_date.strftime('%Y-{0}-31'.format(current_month))
employee_permissions = self.search([
('employee_id', '=', item.employee_id.id),
('state', '=', 'approve'),
('date_from', '>=', date_from),
('date_to', '<=', date_to)])
all_perission = 0
for rec in employee_permissions:
all_perission += rec.duration
if number_of_per < all_perission:
raise ValidationError(_('Sorry You Have Used All Your Permission Hours In This Month'))
start_date_value = datetime.strptime(str(item.date_from), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
if start_date_value <= end_date:
days = (end_date - start_date_value).days
seconds_diff = (end_date - start_date_value).seconds
item.duration = (days * 24) + seconds_diff / 3600
if item.duration <= 0.0:
raise exceptions.Warning(_('This Duration Must Be Greater Than Zero'))
if item.duration < item.balance:
raise exceptions.Warning(_('This Duration must be less than or equal to the Permission Limit'))
if item.duration > item.permission_number:
raise exceptions.Warning(
_('This Duration not Allowed it must be Less Than or equal Permission Hours in Month'))
if employee_permissions.date_to and item.date_to:
permission_date = datetime.strptime(str(employee_permissions.date_to),
DEFAULT_SERVER_DATETIME_FORMAT).date()
date_to_value = datetime.strptime(str(item.date_to), DEFAULT_SERVER_DATETIME_FORMAT).date()
if permission_date == date_to_value:
raise exceptions.Warning(
_('Sorry You Have Used All Your Permission In This Day you have one permission per a Day'))
else:
raise exceptions.Warning(_('End Date must be greater than Start Date'))
@api.constrains('date_from', 'date_to')
def _get_date_constrains2(self):
for item in self:
start_date_value = datetime.strptime(str(item.date_from), "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(str(item.date_to), "%Y-%m-%d %H:%M:%S")
if start_date_value > end_date:
raise exceptions.Warning(_('End Date must be greater than Start Date'))
def draft_state(self):
self.state = "draft"
self.call_cron_function()
def call_cron_function(self):
date = datetime.strptime(str(self.date), "%Y-%m-%d")
self.env['hr.attendance.transaction'].process_attendance_scheduler_queue(date, self.employee_id)
# @api.constrains('date_from', 'date_to')
def send(self):
self._get_date_constrains2()
self.state = "send"
def direct_manager(self):
self.state = "direct_manager"
def approve(self):
self.state = "approve"
self.call_cron_function()
def refused(self):
self.state = "refused"
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(HrPersonalPermission, self).unlink()
class HrPersonalPermissionAttach(models.Model):
_inherit = 'ir.attachment'
personal_permission_id = fields.Many2one(comodel_name='hr.personal.permission')

View File

@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _, exceptions
from hijri_converter import convert
class EmployeeOtherRequest(models.Model):
_name = 'employee.other.request'
_rec_name = 'employee_id'
_description = 'Other Request'
_inherit = ['mail.thread', 'mail.activity.mixin']
from_hr = fields.Boolean()
date = fields.Date(default=lambda self: fields.Date.today())
comment = fields.Text()
state = fields.Selection(selection=[('draft', _('Draft')), ('submit', _('Submit')),
('confirm', _('Direct Manager')),
('approved', _('HR Manager')),
('refuse', _('Refuse'))],
default='draft', tracking=True)
request_type = fields.Selection(selection=[('dependent', _('Dependent')),
('insurance', _('Insurance')), ('card', _('Business Card')),
('qualification', _('Qualification')),
('certification', _('Certification')),
('salary_define', _('Salary Define')),
('salary_fixing', _('Salary Fixing')),
('suggestion', _('Suggestion')),
('complaint', _('Complaint')),
('other_requests', _('Other Requests'))], tracking=True)
# relational fields
employee_id = fields.Many2one('hr.employee', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
department_id = fields.Many2one(comodel_name='hr.department', related='employee_id.department_id', readonly=True)
job_id = fields.Many2one(comodel_name='hr.job', related='employee_id.job_id', readonly=True)
contract_statuss = fields.Selection(related='employee_id.contract_id.contract_status', readonly=True)
employee_dependant = fields.One2many('hr.employee.dependent', 'request_id', _('Employee Dependants'))
qualification_employee = fields.One2many('hr.qualification', 'request_id', _('Employee Qualification'))
certification_employee = fields.One2many('hr.certification', 'request_id', _('Employee Certification'))
create_insurance_request = fields.Boolean()
print_type = fields.Selection(selection=[('detail', _("With Details")),
('no_detail', _("Without Details")),
('no_salary', _("Without Salary"))], string='Print Type')
destination = fields.Char(string='Destination')
parent_request_id = fields.Many2one('employee.other.request')
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
def print_with_details(self):
return self.env.ref('employee_requests.action_report_employee_identification').report_action(self)
def print_with_details2(self):
return self.env.ref('employee_requests.action_report_employee_identify_2').report_action(self)
def print_with_details3(self):
return self.env.ref('employee_requests.action_report_employee_identify_3').report_action(self)
def print_without_details(self):
return self.env.ref('employee_requests.action_report_employee_identify_3').report_action(self)
def print_salary_confirmation(self):
return self.env.ref('employee_requests.salary_conf_report_act').report_action(self)
'''@api.onchange('employee_id')
def chick_hiring_date(self):
for item in self:
if item.employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(
_('You can not Request Other Request The Employee have Not First Hiring Date'))'''
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
def submit(self):
for item in self:
if item.employee_id:
if not item.employee_id.first_hiring_date:
raise exceptions.Warning(
_('You can not Request Other Request The Employee have Not First Hiring Date'))
if item.request_type == 'dependent':
if not item.employee_dependant:
raise exceptions.Warning(_('Please The dependents were not Included'))
if item.employee_id.contract_id.contract_status == 'single':
raise exceptions.Warning(_('You can not Add Fimaly record Because Employee is Single'))
else:
item.state = "submit"
if item.request_type == 'qualification':
if not item.qualification_employee:
raise exceptions.Warning(_('Please The qualification or certification were not Insert Below!'))
for rec in item.qualification_employee:
if not rec.attachment:
raise exceptions.Warning(_('Please Insert Attachments Files Below!'))
else:
item.state = "submit"
if item.request_type == 'certification':
if not item.certification_employee:
raise exceptions.Warning(_('Please The qualification or certification were not Insert Below!'))
for rec in item.certification_employee:
if not rec.attachment:
raise exceptions.Warning(_('Please Insert Attachments Files Below!'))
else:
item.state = "submit"
else:
item.state = "submit"
def confirm(self):
self.state = 'confirm'
def approved(self):
for item in self:
if item.request_type == 'dependent':
if item.employee_dependant:
item.employee_dependant.write({
'contract_id': item.employee_id.contract_id.id,
})
if self.create_insurance_request:
self.env['employee.other.request'].create({
'employee_id': item.employee_id.id,
'department_id': item.department_id.id,
'job_id': item.job_id.id,
'contract_statuss': item.contract_statuss,
'date': item.date,
'request_type': 'insurance',
'parent_request_id': item.id,
'comment': item.comment,
# 'employee_dependant': [(0, 0, line) for line in line_vals],
'state': 'submit'
})
if item.request_type == 'qualification':
if item.qualification_employee:
item.qualification_employee.write({
'qualification_relation_name': item.employee_id.id,
})
if item.request_type == 'certification':
if item.certification_employee:
item.certification_employee.write({
'certification_relation': item.employee_id.id,
})
self.state = 'approved'
def refuse(self):
for item in self:
if item.request_type == 'dependent':
if item.employee_dependant:
item.employee_dependant.write({
'contract_id': False
})
if item.request_type == 'qualification':
if item.qualification_employee:
item.qualification_employee.write({
'qualification_relation_name': False
})
if item.request_type == 'certification':
if item.certification_employee:
item.certification_employee.write({
'certification_relation': False
})
self.state = 'refuse'
def draft(self):
for item in self:
if item.request_type == 'dependent':
if item.employee_dependant:
item.employee_dependant.write({
'contract_id': False
})
self.state = 'draft'
def change_current_date_hijri(self):
date = fields.Date.from_string(self.date)
year = date.year
day = date.day
month = date.month
hijri_date = convert.Gregorian(year, month, day).to_hijri()
return hijri_date
# Hr_Employee_dependent
class EmployeeDependent(models.Model):
_inherit = 'hr.employee.dependent'
request_id = fields.Many2one('employee.other.request')
# Hr_Employee_Qualification
class Qualification(models.Model):
_inherit = 'hr.qualification'
request_id = fields.Many2one('employee.other.request')
# Hr_Employee_Certification
class HrCertification(models.Model):
_inherit = 'hr.certification'
request_id = fields.Many2one('employee.other.request')

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from . import report_employee_identification
from . import report_employee_identification1
from . import report_employee_identification2

View File

@ -0,0 +1,419 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="custom_external_layout_standard">
<div class="header">
<div class="row">
<table style="width:100%;border: 1px solid gray;height:100px">
<tr style=" border: 1px solid gray">
<td style=" border: 1px solid gray;width:50%;padding:5px">
<h4>
<center>TAQNIA SPACE</center>
<br/>
Mobile No:
</h4>
</td>
<td style=" border: 1px solid gray;width:50%">
<img t-if="company.logo" t-att-src="'data:image/png;base64,%s' % to_text(company.logo)" style="max-height:100px;width:70%"/>
</td>
</tr>
</table>
</div>
</div>
<div class="article o_report_layout_standard">
<t t-raw="0" />
</div>
</template>
<template id="custom_external_layout">
<!-- Multicompany -->
<t t-if="not o and doc">
<t t-set="o" t-value="doc"/>
</t>
<t t-if="o and 'company_id' in o">
<t t-set="company" t-value="o.company_id.sudo()"/>
</t>
<t t-if="not o or not 'company_id' in o">
<t t-set="company" t-value="res_company"/>
</t>
<t t-call="employee_requests.custom_external_layout_standard"><t t-raw="0"/></t>
<!-- <t t-if="company.external_report_layout_id == 'background'">-->
<!-- <t t-call="employee_requests.custom_external_layout_standard"><t t-raw="0"/></t>-->
<!-- </t>-->
<!-- <t t-if="company.external_report_layout_id == 'boxed'">-->
<!-- <t t-call="employee_requests.custom_external_layout_standard"><t t-raw="0"/></t>-->
<!-- </t>-->
<!-- <t t-if="company.external_report_layout_id == 'clean'">-->
<!-- <t t-call="employee_requests.custom_external_layout_standard"><t t-raw="0"/></t>-->
<!-- </t>-->
<!-- <t t-if="company.external_report_layout in (False, 'standard')">-->
<!-- <t t-call="employee_requests.custom_external_layout_standard"><t t-raw="0"/></t>-->
<!-- </t>-->
</template>
<template id="clearance_report_template">
<t t-call="web.html_container">
<t t-call="employee_requests.custom_external_layout">
<style type="text/css">
@font-face {
font-family: 'ae_AlMohanad';
src: local('ae_AlMohanad'), local('ae_AlMohanad'),
url('/employee_requests/static/fonts/ae_AlMohanad.ttf') format('truetype');
}
*{
font-family: ae_AlMohanad;
}
</style>
<div class="page" style="font-size:11pt" dir="ltr">
<t t-foreach="docs" t-as="o">
<div style="width:100%">
<center>
<p style="font-weight:bold">Station clearance form</p>
</center>
<p style="margin-left:5%;">(to be completed 2 week prior to end of service and submitted to HR regional office for final settlement )</p>
</div>
<br/>
<table style="width:100%;border: 1px solid gray;height:60px">
<tr>
<td style=" border: 1px solid gray;width:20%;">
Name
</td>
<td style="border: 1px solid gray;width:30%"><span t-esc="o.employee_id.name"/></td>
<td style=" border: 1px solid gray;width:20%;">
Job Title
</td>
<td style="border: 1px solid gray;width:30%"><span t-esc="o.job_id.name"/></td>
</tr>
<tr>
<td style=" border: 1px solid gray;width:20%;">PF#</td>
<td style="color:white; border: 1px solid gray;width:30%">.</td>
<td style=" border: 1px solid gray;width:20%;">Department</td>
<td style="border: 1px solid gray;width:30%"><span t-esc="o.department_id.name"/></td>
</tr>
<tr>
<td style=" border: 1px solid gray;width:20%;">Last working day</td>
<td style="border: 1px solid gray;width:30%"><span t-esc="o.date_deliver_work"/></td>
<td style=" border: 1px solid gray;width:20%;">Leave Date</td>
<td style="border: 1px solid gray;width:30%"><span t-esc="o.employee_id.leaving_date"/></td>
</tr>
</table>
<center><p>Check out items</p></center>
<table style="width:100%;border: 1px solid gray;">
<tr>
<td style="width:3%;background-color:#d3d3d3;">1.
</td>
<td style="width:73%;background-color:#d3d3d3;">
DEPARTMENT HEAD
</td>
<td style="width:10%;background-color:#d3d3d3;">
Signature
</td>
<td style="width:13%;background-color:#d3d3d3;">Date</td>
</tr>
<tr>
<td style="width:3%">
A
</td>
<td style="width:73%">
Tools,equipment, uniform(old/new),locker/desk,door keys, and manualsreturned
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
B
</td>
<td style="width:73%">
Others
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%;background-color:#d3d3d3;">
2
</td>
<td style="width:73%;background-color:#d3d3d3;">
INFORMATION AND SYSTEM DEPARTMENT
</td>
<td style="width:10%;background-color:#d3d3d3;">
Signature
</td>
<td style="width:10%;background-color:#d3d3d3;">
Date
</td>
</tr>
<tr>
<td style="width:3%">
A
</td>
<td style="width:73%">
E-mail and internet account disabled.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
B
</td>
<td style="width:73%">
All system password cancelled.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
C
</td>
<td style="width:77%">
Laptops/PC
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:10%">
D
</td>
<td style="width:70%">
Telephones/IP Telephones returned.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
E
</td>
<td style="width:77%">
Others
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%;background-color:#d3d3d3;">
3
</td>
<td style="width:77%;background-color:#d3d3d3;">
ADMINISTRATION DEPARTMENT
</td>
<td style="width:10%;background-color:#d3d3d3;">
Signature
</td>
<td style="width:10%;background-color:#d3d3d3;">
Date
</td>
</tr>
<tr>
<td style="width:3%">
A
</td>
<td style="width:77%">
Furniture office /equipment have returned(if applicable).
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
B
</td>
<td style="width:77%">
Vehicle parking sticker returned(if applicable).
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:10%">
C
</td>
<td style="width:70%">
Car returned
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
D
</td>
<td style="width:77%">
Others
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%;background-color:#d3d3d3;">
4
</td>
<td style="width:77%;background-color:#d3d3d3;">
FINANCE DEPARTMENT
</td>
<td style="width:10%;background-color:#d3d3d3;">
Signature
</td>
<td style="width:10%;background-color:#d3d3d3;">
Date
</td>
</tr>
<tr>
<td style="width:3%">
A
</td>
<td style="width:77%">
Petty Cash.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
B
</td>
<td style="width:77%">
Credit Control.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
C
</td>
<td style="width:77%">
Finance Control.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
D
</td>
<td style="width:77%">
Others
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%;background-color:#d3d3d3;">
5
</td>
<td style="width:77%;background-color:#d3d3d3;">
HUMAN RESOURCE DEPARTMENT
</td>
<td style="width:10%;background-color:#d3d3d3;">
Signature
</td>
<td style="width:10%;background-color:#d3d3d3;">
Date
</td>
</tr>
<tr>
<td style="width:3%">
A
</td>
<td style="width:77%">
Bank guarantee letters checked and clearance certificate received from bank.(if applicable)
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
B
</td>
<td style="width:77%">
Training courses guarantee cleared (if applicable),Employee need to pay the amount of ....... riyals to cover training expanses.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
C
</td>
<td style="width:77%">
Employee fills exit interview and submit it.
</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
D
</td>
<td style="width:77%">
Medical insurance card.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
E</td>
<td style="width:77%">
Identity returned and exit procedure completed(expatriat staff only).</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
F</td>
<td style="width:77%">
GOSI deletion</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
G</td>
<td style="width:77%">
All ID/access cards returned</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
<tr>
<td style="width:3%">
H</td>
<td style="width:77%">
Others</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
<td style="color:white; border: 1px solid gray;width:10%">.</td>
</tr>
</table>
<style>
table{
width:100%;
}
td{
border: 1px solid grey;
padding: 1px 1px 1px 1px;
}
th{
border: 1px solid grey;
padding: 1px 1px 1px 1px;
font-weight: bold;
background-color:#d3d3d3;
}
</style>
</t>
</div>
</t>
</t>
</template>
<record id="custom_clearances_action_report" model="ir.actions.report">
<field name="model">hr.clearance.form</field>
<field name="name">Clearance Form</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.clearance_report_template</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<template id="disclaimer_certificate_report">
<t t-call="web.html_container" t-translation="off">
<t t-call="hr_base.hr_layout">
<div class="page" style="font-size:18pt;direction:rtl">
<style>
@font-face {font-family: "Sakkal Majalla"; src: url("/exp_socpa_hr_report/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot"); src: url("/exp_socpa_hr_report/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot?#iefix") format("embedded-opentype"), url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff2") format("woff2"), url("/exp_socpa_hr_report/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff") format("woff"), url("/exp_socpa_hr_report/static/fonts/ce7b5754581057e6f7444e2192850cc8.ttf") format("truetype"); }
</style>
<t t-foreach="docs" t-as="o">
<br/>
<br/>
<div class="row"
style="margin-bottom: 10px;font-family: 'Sakkal Majalla'!important;font-size: 17pt;">
<div class="row">
<span style="margin-right: 8%;">
التاريخ :
</span>
<span style="font-size: 18px;" t-esc="o.employee_id.change_current_date_hijri()"/>
<br/>
<span style="margin-right: 8%;">
الموافق :
</span>
<span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d')"/>
</div>
<br/>
<div class="row">
<p style="text-align: center;color:#204a87">
<strong>
شهادة إخلاء طرف
</strong>
<br/>
</p>
<br/>
</div>
<br/>
<br/>
<p style="text-align:justify;margin-right:6%;margin-left:6%;color:black; line-height: 1.7;">
<span style="color:black; font-weight: bold;">السلام عليكم ورحمة الله و بركاته:
</span>
</p>
<br/>
<div>
<p style="text-align:justify;margin-right:6%;margin-left:6%;color:black; line-height: 1.7;">
تشهد
<span t-esc="o.employee_id.company_id.name"/>
بأن السيد /<span
t-field="o.employee_id.name"/>, يحمل بطاقة
أحوال رقم
<t t-if="o.employee_id.country_id.name == 'Saudi Arabia' or o.employee_id.country_id.name == 'المملكة العربية السعودية'">
<span t-field="o.employee_id.saudi_number.saudi_id"/>
</t>
<t t-else="">
<span t-field="o.employee_id.iqama_number.iqama_id"/>
</t>
و الذي تقدم بإستقالته في تاريخ
<span t-esc="o.date"/>
بأنه ليس للهيئة أي
إلتزامات عليه أو له خلال فترة عمله لدينا من تاريخ
<span t-esc="o.employee_id.contract_id.date_start"/>
وحتى تاريخ
<span t-esc="o.date_deliver_work"/>
, ويعتبر خالي
الطرف لدينا .
</p>
<p style="text-align:justify;margin-right:6%;margin-left:6%;color:black; line-height: 1.7;">
هذا وقد أعطي هذه الشهادة لتقديمها إلى من يهمه الأمر
</p>
<br/>
<br/>
</div>
<div class="row">
<h2 style="text-align: center;">
<strong>و الله ولي التوفيق ,,,</strong>
<br/>
<br/>
<strong>إدارة الموارد البشرية</strong>
</h2>
<br/>
</div>
</div>
</t>
</div>
</t>
</t>
</template>
<record id="disclaimer_report_act" model="ir.actions.report">
<field name="model">hr.clearance.form</field>
<field name="name">Disclaimer Certificate Report</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.disclaimer_certificate_report</field>
<field name="report_file">employee_requests.disclaimer_certificate_report</field>
<field name="groups_id" eval="[(4, ref('hr.group_hr_user'))]"/>
</record>
</data>
</odoo>

View File

@ -0,0 +1,228 @@
<?xml version="1.0"?>
<odoo>
<!-- <template id="employee_request_external_layout_standard" inherit_id="web.external_layout_standard">-->
<!-- <xpath expr="//div[@class='header']" position="replace"/>-->
<!-- <xpath expr="//div[@class='footer']" position="replace"/>-->
<!-- </template>-->
<template id="employee_appointment_template">
<t t-call="web.html_container">
<t t-call="hr_base.hr_layout">
<t t-foreach="docs" t-as="o">
<div class="page" style="font-size:18;direction:ltr" >
<div class="oe_structure"/>
<div class="page-header" >
<div class="text-center">
<b>Appointment Report</b><br/>
</div>
</div>
</div>
<table class="table table-bordered">
<tr style="font-size:16;">
<td>
<strong>Number</strong>
</td>
<td class="text-center"><span t-field="o.emp_no"/></td>
<td colspan="4"></td>
<td >
<strong>Date</strong>
</td>
<td class="text-center"></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Iqama</strong>
</td>
<td colspan="2" class="text-center">
<t t-if="o.country_id.code=='SA'">
<t t-esc="o.saudi_number.saudi_id"/>
</t>
<t t-else="">
<t t-esc="o.iqama_number.iqama_id"/>
</t>
</td>
<td colspan="5"></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Name</strong>
</td>
<td colspan="2" class="text-center"><span t-field="o.name"/></td>
<td colspan="3"></td>
<td>
<strong>Status</strong>
</td>
<td class="text-center"><span t-field="o.marital"/></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Nationality</strong>
</td>
<td class="text-center"><span t-field="o.country_id.name"/></td>
<td>
<strong>Gender</strong>
</td>
<td class="text-center"><span t-field="o.gender"/></td>
<td>
<strong>Birth Date</strong>
</td>
<td class="text-center"><span t-field="o.birthday"/></td>
<td>
<strong>Age</strong>
</td>
<t t-if="o.birthday">
<td class="text-center"><span t-esc="context_timestamp(datetime.datetime.now()).year - datetime.datetime.strptime(str(o.birthday), '%Y-%m-%d').date().year"/></td>
</t>
</tr>
<tr style="font-size:16;">
<td>
<strong>City</strong>
</td>
<td class="text-center"><span t-field="o.address_city.name"/></td>
<td colspan="6"></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Job</strong>
</td>
<td class="text-center"><span t-field="o.iqama_number.job_id.name"/></td>
<td>
<strong>Real Job</strong>
</td>
<td class="text-center"><span t-field="o.job_id.name"/></td>
<td>
<strong>Department</strong>
</td>
<td colspan="3" class="text-center"><span t-field="o.department_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Manager</strong>
</td>
<td class="text-center"><span t-field="o.parent_id.name"/></td>
<td colspan="2"></td>
<td colspan="4"></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Company</strong>
</td>
<td class="text-center"><span t-field="o.company_id.name"/></td>
<td colspan="2"></td>
<td colspan="4"></td>
</tr>
</table>
<center><b>Salary Info</b></center><br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td><strong>Base Salary</strong></td>
<td class="text-center"><span t-field="o.contract_id.salary"/></td>
<td><strong>Additional</strong></td>
<td class="text-center"><span t-esc="o.contract_id.total_allowance - (o.contract_id.salary + o.contract_id.house_allowance_temp + o.contract_id.transport_allowance)"/></td>
<td><strong>Allowances</strong></td>
<td colspan="1" class="text-center"> <span t-field="o.contract_id.house_allowance_temp"/></td>
<td colspan="3" class="text-center"><span t-field="o.contract_id.transport_allowance"/></td>
<td colspan="3"><strong>Total</strong></td>
<td colspan="3" class="text-center"><span t-esc="o.contract_id.salary + o.contract_id.house_allowance_temp + o.contract_id.transport_allowance"/></td>
</tr>
<tr style="font-size:16;">
<td></td>
<td></td>
<td colspan="7"></td>
<td>
<strong>Net</strong>
</td>
<td colspan="3" class="text-center"><span t-field="o.contract_id.total_net"/></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Bank 1</strong>
</td>
<td class="text-center"><span t-field="o.bank_code"/></td>
<td colspan="2">
<strong>Bank 2</strong>
</td>
<td colspan="2">
<strong>Account Number</strong>
</td>
<td colspan="7" class="text-center"><span t-field="o.bank_account_id.acc_number"/></td>
</tr>
</table>
<center><b>Documents</b></center>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td><strong>Identity End Date</strong></td>
<td colspan="2"><span t-field="o.iqama_number.expiry_date"/></td>
<td colspan="2"></td>
<td colspan="4"></td>
</tr>
<tr style="font-size:16;">
<td><strong>Passport Number</strong></td>
<td class="text-center"><span t-field="o.passport_id.name"/></td>
<td><strong>Passport Issuance Date</strong></td>
<td colspan="2" class="text-center"><span t-field="o.date_issuance_passport"/></td>
<td><strong>Passport Expiration Date</strong></td>
<td colspan="2" class="text-center"><span t-field="o.expiration_date_passport"/></td>
</tr>
</table>
<center><b>Work</b></center>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td><strong>Hiring Date</strong></td>
<td class="text-center"><span t-field="o.first_hiring_date"/></td>
<td><strong>Contract Start Date</strong></td>
<td class="text-center"><span t-field="o.contract_id.date_start"/></td>
<td><strong>Contract End Date</strong></td>
<td class="text-center"><span t-field="o.contract_id.date_end"/></td>
<td></td>
</tr>
</table>
<center><b>Contact</b></center>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td>
<strong>Phone</strong>
</td>
<td class="text-center"><span t-field="o.work_phone"/></td>
<td>
<strong>Mobile</strong>
</td>
<td class="text-center"><span t-field="o.mobile_phone"/></td>
<td colspan="2"></td>
</tr>
<tr style="font-size:16;">
<td>
<strong>Email</strong>
</td>
<td colspan="2" class="text-center"><span t-field="o.work_email"/></td>
<td>
<strong>Address</strong>
</td>
<td colspan="2" class="text-center"><span t-field="o.address_id"/></td>
</tr>
</table>
<center><b>Notes</b></center>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td></td>
</tr>
</table>
<br/>
</t>
</t>
</t>
</template>
<record id="employee_appointment_action_report" model="ir.actions.report">
<field name="model">hr.employee</field>
<field name="name">Employee Appointment Report</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.employee_appointment_template</field>
</record>
</odoo>

View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="action_report_employee_clearance_details" model="ir.actions.report">
<field name="model">hr.clearance.form</field>
<field name="report_type">qweb-pdf</field>
<field name="name">نموذج إخلاء طرف</field>
<field name="report_name">employee_requests.employee_clearance_details_template</field>
<field name="report_file">employee_requests.employee_clearance_details_template</field>
</record>
<record id="action_report_employee_clearance" model="ir.actions.report">
<field name="model">hr.clearance.form</field>
<field name="report_type">qweb-pdf</field>
<field name="name">employee Clearance</field>
<field name="report_name">employee_requests.employee_clearance_form_template</field>
<field name="report_file">employee_requests.employee_clearance_form_template</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,138 @@
<?xml version="1.0"?>
<odoo>
<data>
<template id="employee_clearance_form_template">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<div class="page" style="font-size:18;direction:ltr" >
<div class="oe_structure"/>
<div class="page-header" >
</div>
<div class="text-center">
<b>إخلاء طرف</b>
<br/>
<b >(Clearance)</b>
</div>
<br/>
<br/>
<t t-foreach="docs" t-as="d">
<table class="table table-bordered">
<tr style="font-size:16;">
<td >Date :
</td>
<td class="text-center" ><span t-field="d.date"/></td>
</tr>
<tr style="font-size:16;">
<td >
name :
</td>
<td class="text-center"><span t-field="d.employee_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td>
number :
</td>
<td class="text-center"><span t-field="d.employee_id.emp_no"/></td>
</tr>
<tr style="font-size:16;">
<td>
Job Title :
</td>
<td class="text-center"><span t-field="d.employee_id.job_id"/></td>
</tr>
<tr style="font-size:16;">
<td >
Department :
</td>
<td class="text-center" ><span t-field="d.employee_id.department_id"/></td>
</tr>
<tr style="font-size:16;">
<td>
Division :
</td>
<td class="text-center"><span t-field="d.employee_id.department_id"/></td>
</tr>
</table>
<br/>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td>Telephone operator :
</td>
<td >Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Medical cards :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>Identity cards :
</td>
<td >Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Receiving driving License :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Vehicle control :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Section Head :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Department Head :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Finance Head :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Project Manager :
</td>
<td>Signature :/</td>
</tr>
<tr style="font-size:16;">
<td>
Administration Manager :
</td>
<td>Signature :/</td>
</tr>
</table>
</t>
</div>
<div class="page-footer">
<b class="text-center">notes :..................................................................................................................</b>
<br/>
<b class="text-center">main copy to Employee</b>
<br/>
<b class="text-center">a copy to Finance</b>
<br/>
</div>
</t>
</t>
</template>
</data>
</odoo>

View File

@ -0,0 +1,219 @@
<?xml version="1.0"?>
<odoo>
<data>
<template id="employee_clearance_details_template">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<div class="page" style="font-size:18;direction:ltr" >
<div class="oe_structure"/>
<div class="page-header" >
<div class="text-right" style="background-color:orange;">
<b>نموذج إخلاء طرف</b>
<br/>
<b >(DisClaimer Form)</b>
<br/>
REF#HR-F:<span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>
</div>
</div>
<t t-foreach="docs" t-as="d">
<table class="table table-bordered">
<tr style="font-size:16;">
<td >
Department :
</td>
<td class="text-center" >
<span t-field="d.employee_id.department_id"/></td>
<td >
name :
</td>
<td class="text-center"><span t-field="d.employee_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td>
Direct Manager :
</td>
<td class="text-center"><span t-field="d.employee_id.parent_id"/></td>
<td>
Employee Number :
</td>
<td class="text-center"><span t-field="d.employee_id.emp_no"/></td>
</tr>
<tr style="font-size:16;">
<td>
Last Working Day :
</td>
<td class="text-center"><span t-field="d.date_deliver_work"/></td>
<td>
Job Title :
</td>
<td class="text-center"><span t-field="d.employee_id.job_id"/></td>
</tr>
</table>
<table class="table table-bordered">
<thead>
<tr style="font-size:16;">
<th>
Department
</th>
<th>Details</th>
<th>
Name
</th>
<th > Signature</th>
</tr>
</thead>
<tbody>
<tr style="font-size:16;">
<td>
Direct Management
</td>
<td>
<table class="table table-bordered">
<tr >
<td>Office Content</td>
</tr>
<tr>
<td>Work Related Document Delivered</td>
</tr>
<tr>
<td>Work Related information Delivered</td>
</tr>
<tr>
<td>Equipment Delivered</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
</tr>
</table>
</td>
<td>
<table>
<tr>
</tr>
</table>
</td>
</tr>
<tr style="font-size:16;">
<td>
IT Department
</td>
<td class="table table-bordered">
<table class="table table-bordered" >
<tr>
<td>Server Account Stopped</td>
</tr>
<tr>
<td>User e-mail Stopped</td>
</tr>
<tr>
<td>Laptop Delivered</td>
</tr>
<tr>
<td>Mobile Phone Delivered</td>
</tr>
<tr>
<td>Internal Extension Stopped</td>
</tr>
<tr>
<td>Wireless Network Account
Stopped</td>
</tr>
<tr>
<td>User Deleted from Time
Management</td>
</tr>
<tr>
<td>User Deleted from Mina</td>
</tr>
<tr>
<td> HDD Usage Delivered</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
</tr>
</table>
</td>
<td>
<table>
<tr>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<br/>
<br/>
</t>
</div>
<div class="page-footer">
<div class="text-center">
<b class="text-center">مدير إدارة الموارد البشرية</b>
<br/>
<b class="text-center">HR Manager</b>
<br/>
</div>
</div>
</t>
</t>
</template>
</data>
</odoo>

View File

@ -0,0 +1,88 @@
<?xml version="1.0"?>
<odoo>
<template id="employee_department_jobs_template">
<t t-call="web.html_container">
<t t-call="hr_base.hr_layout">
<t t-foreach="docs" t-as="o">
<div class="page" style="font-size:18;direction:ltr" >
<div class="oe_structure"/>
<div class="page-header" >
<div class="text-center">
<b>Employee Department and Jobs</b><br/>
</div>
</div>
</div>
<table class="table table-bordered">
<tr style="font-size:16;">
<td>
Number :
</td>
<td class="text-center" ></td>
<td >
Date :
</td>
<td class="text-center"><span t-field="o.date"/></td>
</tr>
</table>
<br/>
<table class="table table-bordered">
<tr style="font-size:16;">
<td colspan="3">
Employee :
</td>
<td colspan="3" class="text-center"><span t-field="o.employee_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td>
Iqama :
</td>
<td class="text-center">
<t t-if="o.employee_id.country_id.code== 'SA'">
<t t-esc="o.employee_id.saudi_number.saudi_id"/>
</t>
<t t-else="">
<t t-esc="o.employee_id.iqama_number.iqama_id"/>
</t>
</td>
<td>
Nationality :
</td>
<td class="text-center"><span t-field="o.employee_id.country_id.name"/></td>
<td>
Old Job Title :
</td>
<td class="text-center"><span t-field="o.old_job_2_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td>
Source :
</td>
<td class="text-center"><span t-field="o.old_department_2_id.name"/></td>
<td>
Destination :
</td>
<td class="text-center"><span t-field="o.new_department_id.name"/></td>
<td>
New Job Title :
</td>
<td class="text-center"><span t-field="o.new_job_id.name"/></td>
</tr>
<tr style="font-size:16;">
<td colspan="6" class="text-center">This is will be applied from <span t-field="o.date"/></td>
</tr>
</table>
<br/><br/>
</t>
</t>
</t>
</template>
<record id="employee_department_jobs_action_report" model="ir.actions.report">
<field name="model">employee.department.jobs</field>
<field name="name">Employee Department and Jobs Report</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.employee_department_jobs_template</field>
</record>
</odoo>

View File

@ -0,0 +1,20 @@
from odoo import models, api
from odoo.exceptions import UserError
from odoo.tools.translate import _
class EmployeeVacation(models.AbstractModel):
_name = "report.employee_requests.report_employee_identification"
@api.model
def _get_report_values(self, docids, data):
docs = self.env['employee.other.request'].browse(docids)
for record in docs:
if record.state != 'approved':
raise UserError(_("Sorry, you cannot print the report until final approval of the request"))
docargs = {
'doc_ids': [],
'doc_model': ['employee.other.request'],
'docs': docs,
}
return docargs

View File

@ -0,0 +1,20 @@
from odoo import models, api
from odoo.exceptions import UserError
from odoo.tools.translate import _
class EmployeeVacation(models.AbstractModel):
_name = "report.employee_requests.report_employee_identify_3"
@api.model
def _get_report_values(self, docids, data):
docs = self.env['employee.other.request'].browse(docids)
for record in docs:
if record.state != 'approved':
raise UserError(_("Sorry, you cannot print the report until final approval of the request"))
docargs = {
'doc_ids': [],
'doc_model': ['employee.other.request'],
'docs': docs,
}
return docargs

View File

@ -0,0 +1,20 @@
from odoo import models, api
from odoo.exceptions import UserError
from odoo.tools.translate import _
class EmployeeVacation(models.AbstractModel):
_name = "report.employee_requests.report_employee_identify_2"
@api.model
def _get_report_values(self, docids, data):
docs = self.env['employee.other.request'].browse(docids)
for record in docs:
if record.state != 'approved':
raise UserError(_("Sorry, you cannot print the report until final approval of the request"))
docargs = {
'doc_ids': [],
'doc_model': ['employee.other.request'],
'docs': docs,
}
return docargs

View File

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_employee_identification">
<t t-call="web.html_container" t-translation="off">>
<div class="header">
<div class="row text-center">
<!--<img src="/hr_custom_workflow/static/img/header.png" style="width:100%;" class="text-center"/>-->
</div>
</div>
<t t-foreach="docs" t-as="doc">
<div class="article" style="font-family:'Sakkal Majalla'!important;font-size:18pt;direction:rtl">
<style>
@font-face {font-family: "Sakkal Majalla"; src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot"); src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot?#iefix")
format("embedded-opentype"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff2") format("woff2"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff") format("woff"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.ttf") format("truetype");
}
#content-table thead tr th{
background-color: rgb(77, 168, 178);
border: 1px solid #222;
vertical-align: middle;
font-weight: bold;
text-align:center;
color: #fff;
padding: 10px 0;
font-size: 16pt;
}
#content-table td{
font-family: 'Sakkal Majalla'!important;
}
#content-table thead tr th{
width: 50%;
font-family: 'Sakkal Majalla'!important;
}
#content-table tbody tr td{
border: 1px solid;
vertical-align: middle;
padding: 10px 0;
text-align: center;
font-size:14pt;
}
#content-table tbody tr td:last-child{
direction: ltr;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 25%;
}
#content-table tbody tr td:first-child{
direction: rtl;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 25%;
}
</style>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<h3 style="font-weight:bold;margin-bottom: 40px;text-align:center;font-family: 'Sakkal Majalla'!important;color:rgb(77, 168, 178);font-size: 20pt;margin-top: 0;">
<span>شهادة تعريف</span>
|
<span>Employment Certificate</span>
</h3>
</div>
<table class="table table-borderless" style="margin-bottom: 10px;font-family: 'Sakkal Majalla'!important;font-size: 14pt;
background-size: 35%; background-position: right;background-repeat: no-repeat;">
<tr style="border:0;">
<td style="text-align:right;width:50%;padding-left:50px;padding-right: 20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">مقدم إلى:</span>
<span t-esc="doc.destination"/>
</p>
<span>نفيدكم بأن الموظف الموضح هويته أدنا يعمل لدى</span>
<span style="font-weight: bold;"><span t-esc="env.user.company_id.name"/>-</span>
<span>ولا يزال على رأس العمل حتى تاريخه و أعطيت له هذه الشهادة بناء على</span>
<span>طلبه دون أدنى مسئولية.</span>
</td>
<td style="direction:ltr;text-align:left;border:0;width:50%;padding-right: 50px;padding-left:20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">Addressed To:</span>
<span t-esc="doc.destination"/>
</p>
<span>This is to certify that Below-mentioned employee is working in</span>
<span style="font-weight: bold;">
<span t-esc="env.user.company_id.english_name"/>
-
</span>
<span>This certification</span>
<span>is issued</span>
<span>upon the request of the employee without any obligation</span>
</td>
</tr>
</table>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<div class="TableContainer SCXW182515882 BCX2">
<table id="content-table" aria-rowcount="12" border="1"
class="Table Rtl TableWordWrap SCXW182515882 BCX2"
data-tablelook="1184" data-tablestyle="MsoTableGrid" style="margin-right:13%;">
<thead>
<tr>
<th colspan="2">إفادة عمل</th>
<th colspan="2">Certificate of Employment</th>
</tr>
</thead>
<tbody class="SCXW182515882 BCX2">
<tr>
<td>التاريخ</td>
<td colspan="2">
<span t-esc="doc.date"/>
</td>
<td>Date</td>
</tr>
<tr>
<td>رقم الموظف</td>
<td colspan="2">
<span t-esc="doc.employee_id.emp_no"/>
</td>
<td>Emp No.</td>
</tr>
<tr>
<td>اسم الموظف</td>
<td>
<span t-esc="doc.employee_id.name"/>
</td>
<td>
<span t-esc="doc.employee_id.english_name"/>
</td>
<td>Name</td>
</tr>
<tr>
<td>الوظيفة الحالية</td>
<td colspan="2">
<span t-esc="doc.employee_id.job_id.name"/>
</td>
<td>Position</td>
</tr>
<tr>
<td>رقم الهوية</td>
<td colspan="2">
<span t-esc="doc.employee_id.saudi_number.saudi_id or doc.employee_id.iqama_number.iqama_id"/>
</td>
<td>ID No.</td>
</tr>
<tr>
<td>الجنسية</td>
<td colspan="2">
<span t-esc="doc.employee_id.country_id.name"/>
</td>
<td>Nationality</td>
</tr>
<tr>
<td>الراتب الأساسي</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.salary"/>
<span>ريال</span>
</td>
<td>Basic Salary</td>
</tr>
<tr>
<td>بدل السكن</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.house_allowance_temp"/>
<span>ريال</span>
</td>
<td>Housing Allowance</td>
</tr>
<tr>
<td>بدل النقل</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.transport_allowance"/>
<span>ريال</span>
</td>
<td>Transportation Allowance</td>
</tr>
<tr>
<td>الراتب الشهري الإجمالي</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.salary + doc.employee_id.contract_id.house_allowance_temp + doc.employee_id.contract_id.transport_allowance"/>
<span>ريال</span>
</td>
<td>Total Salary / month</td>
</tr>
<tr>
<td>تاريخ التعيين</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.hiring_date"/>
</td>
<td>Hire Date</td>
</tr>
</tbody>
</table>
</div>
<br/>
<h4 style="text-align: center;">
<span>مدير إدارة الموارد البشرية</span>
</h4>
<h4 style="text-align: center;">
<span>Director of Human Resource</span>
</h4>
<h4 style="text-align: center;">
<span>
<span t-esc="env.user.company_id.hr_manager_id.name"/>
</span>
</h4>
</div>
</div>
</t>
</t>
</template>
<record id="action_report_employee_identification" model="ir.actions.report">
<field name="model">employee.other.request</field>
<field name="name">Employee Identify With details</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.report_employee_identification</field>
<field name="report_file">employee_requests.report_employee_identification</field>
<field name="groups_id" eval="[(4, ref('hr.group_hr_user'))]"/>
</record>
</odoo>

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_employee_identify_2">
<t t-call="web.html_container" t-translation="off">
<div class="header">
<div class="row text-center">
<!--<img src="/hr_custom_workflow/static/img/header.png" style="width:100%;" class="text-center"/>-->
</div>
</div>
<t t-foreach="docs" t-as="doc">
<div class="article" style="font-family:'Sakkal Majalla'!important;font-size:18pt;direction:rtl">
<style>
@font-face {font-family: "Sakkal Majalla"; src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot"); src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot?#iefix")
format("embedded-opentype"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff2") format("woff2"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff") format("woff"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.ttf") format("truetype");
}
#content-table thead tr th{
background-color: rgb(77, 168, 178);
border: 1px solid #222;
vertical-align: middle;
font-weight: bold;
text-align:center;
color: #fff;
padding: 10px 0;
font-size: 16pt;
}
#content-table td{
font-family: 'Sakkal Majalla'!important;
}
#content-table thead tr th{
width: 50%;
font-family: 'Sakkal Majalla'!important;
}
#content-table tbody tr td{
border: 1px solid;
vertical-align: middle;
padding: 10px 0;
text-align: center;
font-size:14pt;
}
#content-table tbody tr td:last-child{
direction: ltr;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 25%;
}
#content-table tbody tr td:first-child{
direction: rtl;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 25%;
}
</style>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<h3 style="font-weight:bold;margin-bottom: 60px;text-align:center;font-family: 'Sakkal Majalla'!important;color:rgb(77, 168, 178);font-size: 20pt;margin-top: 0;">
<span>شهادة تعريف</span>
|
<span>Employment Certificate</span>
</h3>
</div>
<table class="table table-borderless" style="margin-bottom: 10px;font-family: 'Sakkal Majalla'!important;font-size: 14pt;
background-size: 35%; background-position: right;background-repeat: no-repeat;">
<tr style="border:0;">
<td style="text-align:right;width:50%;padding-left:50px;padding-right: 20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">مقدم إلى:</span>
<span t-esc="doc.destination"/>
</p>
<span>نفيدكم بأن الموظف الموضح هويته أدنا يعمل لدى</span>
<span style="font-weight: bold;"><span t-esc="env.user.company_id.name"/>-</span>
<span>ولا يزال على رأس العمل حتى تاريخه و أعطيت له هذه الشهادة بناء على</span>
<span>طلبه دون أدنى مسئولية.</span>
</td>
<td style="direction:ltr;text-align:left;border:0;width:50%;padding-right: 50px;padding-left:20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">Addressed To:</span>
<span t-esc="doc.destination"/>
</p>
<span>This is to certify that Below-mentioned employee is working in</span>
<span style="font-weight: bold;">
<span t-esc="env.user.company_id.english_name"/>
-
</span>
<span>This certification</span>
<span>is issued</span>
<span>upon the request of the employee without any obligation</span>
</td>
</tr>
</table>
<br/>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<div class="TableContainer SCXW182515882 BCX2">
<table id="content-table" aria-rowcount="12" border="1"
class="Table Rtl TableWordWrap SCXW182515882 BCX2"
data-tablelook="1184" data-tablestyle="MsoTableGrid" style="margin-right:20%;">
<thead>
<tr>
<th colspan="2">إفادة عمل</th>
<th colspan="2">Certificate of Employment</th>
</tr>
</thead>
<tbody class="SCXW182515882 BCX2">
<tr>
<td>التاريخ</td>
<td colspan="2">
<span t-esc="doc.date"/>
</td>
<td>Date</td>
</tr>
<tr>
<td>رقم الموظف</td>
<td colspan="2">
<span t-esc="doc.employee_id.emp_no"/>
</td>
<td>Emp No.</td>
</tr>
<tr>
<td>اسم الموظف</td>
<td>
<span t-esc="doc.employee_id.name"/>
</td>
<td>
<span t-esc="doc.employee_id.english_name"/>
</td>
<td>Name</td>
</tr>
<tr>
<td>الوظيفة الحالية</td>
<td colspan="2">
<span t-esc="doc.employee_id.job_id.name"/>
</td>
<td>Position</td>
</tr>
<tr>
<td>رقم الهوية</td>
<td colspan="2">
<span t-esc="doc.employee_id.saudi_number.saudi_id or doc.employee_id.iqama_number.iqama_id"/>
</td>
<td>ID No.</td>
</tr>
<tr>
<td>الجنسية</td>
<td colspan="2">
<span t-esc="doc.employee_id.country_id.name"/>
</td>
<td>Nationality</td>
</tr>
<tr>
<td>تاريخ التعيين</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.hiring_date"/>
</td>
<td>Hire Date</td>
</tr>
<tr>
<td>الراتب الشهري الإجمالي</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.total_net"/>
<span>ريال</span>
</td>
<td>Total Salary / month</td>
</tr>
</tbody>
</table>
</div>
<br/>
<br/>
<br/>
<h4 style="text-align: center;">
<span>مدير إدارة الموارد البشرية</span>
</h4>
<h4 style="text-align: center;">
<span>Director of Human Resource</span>
</h4>
<h4 style="text-align: center;">
<span>
<span t-esc="env.user.company_id.hr_manager_id.name"/>
</span>
</h4>
<!--div class="row" style="font-family: 'Sakkal Majalla'!important;">
<div class="col-xs-5">
<p style="direction: ltr;">* <span>Any Alteration or erasures will void this form</span></p>
</div>
<div class="col-xs-3"/>
<div class="col-xs-4">
<p>* <span>اي قشط او تعديل يلغي هذه الشهادة</span></p>
</div>
</div-->
</div>
</div>
</t>
<div class="footer">
<div class="row text-center">
<!--<img src="/hr_custom_workflow/static/img/footer.png" style="width:100%;" class="text-center"/>-->
</div>
</div>
</t>
</template>
<record id="action_report_employee_identify_2" model="ir.actions.report">
<field name="model">employee.other.request</field>
<field name="name">Employee Identify Without Details</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.report_employee_identify_2</field>
<field name="report_file">employee_requests.report_employee_identify_2</field>
<field name="groups_id" eval="[(4, ref('hr.group_hr_user'))]"/>
</record>
</odoo>

View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_employee_identify_3">
<t t-call="web.html_container" t-translation="off">
<div class="header">
<div class="row text-center">
<!--<img src="/hr_custom_workflow/static/img/header.png" style="width:100%;" class="text-center"/>-->
</div>
</div>
<t t-foreach="docs" t-as="doc">
<div class="article" style="font-family:'Sakkal Majalla'!important;font-size:18pt;direction:rtl">
<style>
@font-face {font-family: "Sakkal Majalla"; src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot"); src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot?#iefix")
format("embedded-opentype"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff2") format("woff2"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff") format("woff"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.ttf") format("truetype");
}
#content-table thead tr th{
background-color: rgb(77, 168, 178);
border: 1px solid #222;
vertical-align: middle;
font-weight: bold;
text-align:center;
color: #fff;
padding: 10px 0;
font-size: 16pt;
width: 50%;
}
#content-table td{
font-family: 'Sakkal Majalla'!important;
}
#content-table thead tr th{
width: 50%;
font-family: 'Sakkal Majalla'!important;
}
#content-table tbody tr td{
border: 1px solid;
vertical-align: middle;
padding: 10px 0;
text-align: center;
font-size:14pt;
}
#content-table tbody tr td:last-child{
direction: ltr;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 32%;
}
#content-table tbody tr td:first-child{
direction: rtl;
background-color: rgb(230, 230, 231);
color: #222;
font-weight: bold;
width: 32%;
}
</style>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<h3 style="font-weight:bold;margin-bottom: 60px;text-align:center;font-family: 'Sakkal Majalla'!important;color:rgb(77, 168, 178);font-size: 20pt;margin-top: 0;">
<span>شهادة تعريف</span>
|
<span>Employment Certificate</span>
</h3>
</div>
<table class="table table-borderless" style="margin-bottom: 10px;font-family: 'Sakkal Majalla'!important;font-size: 14pt;
background-size: 35%; background-position: right;background-repeat: no-repeat;">
<tr style="border:0;">
<td style="text-align:right;width:50%;padding-left:50px;padding-right: 20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">مقدم إلى:</span>
<span t-esc="doc.destination"/>
</p>
<span>نفيدكم بأن الموظف الموضح هويته أدنا يعمل لدى</span>
<span style="font-weight: bold;"><span t-esc="env.user.company_id.name"/>-</span>
<span>ولا يزال على رأس العمل حتى تاريخه و أعطيت له هذه الشهادة بناء على</span>
<span>طلبه دون أدنى مسئولية.</span>
</td>
<td style="direction:ltr;text-align:left;border:0;width:50%;padding-right: 50px;padding-left:20px;">
<p style="font-weight: bold;color: #333;margin-bottom: 20px;">
<span style="border-bottom: 1px solid #333;">Addressed To:</span>
<span t-esc="doc.destination"/>
</p>
<span>This is to certify that Below-mentioned employee is working in</span>
<span style="font-weight: bold;">
<span t-esc="env.user.company_id.english_name"/>
-
</span>
<span>This certification</span>
<span>is issued</span>
<span>upon the request of the employee without any obligation</span>
</td>
</tr>
</table>
<br/>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<div class="TableContainer SCXW182515882 BCX2">
<table id="content-table" aria-rowcount="12" border="1"
class="Table Rtl TableWordWrap SCXW182515882 BCX2"
data-tablelook="1184" data-tablestyle="MsoTableGrid" style="margin-right:15%;">
<thead>
<tr>
<th colspan="2">إفادة عمل</th>
<th colspan="2">Certificate of Employment</th>
</tr>
</thead>
<tbody class="SCXW182515882 BCX2">
<tr>
<td>التاريخ</td>
<td colspan="2">
<span t-esc="doc.date"/>
</td>
<td>Date</td>
</tr>
<tr>
<td>رقم الموظف</td>
<td colspan="2">
<span t-esc="doc.employee_id.emp_no"/>
</td>
<td>Emp No.</td>
</tr>
<tr>
<td>اسم الموظف</td>
<td>
<span t-esc="doc.employee_id.name"/>
</td>
<td>
<span t-esc="doc.employee_id.english_name"/>
</td>
<td>Name</td>
</tr>
<tr>
<td>الوظيفة الحالية</td>
<td colspan="2">
<span t-esc="doc.employee_id.job_id.name"/>
</td>
<td>Position</td>
</tr>
<tr>
<td>رقم الهوية</td>
<td colspan="2">
<span t-esc="doc.employee_id.saudi_number.saudi_id or doc.employee_id.iqama_number.iqama_id"/>
</td>
<td>ID No.</td>
</tr>
<tr>
<td>الجنسية</td>
<td colspan="2">
<span t-esc="doc.employee_id.country_id.name"/>
</td>
<td>Nationality</td>
</tr>
<tr>
<td>تاريخ التعيين</td>
<td colspan="2">
<span t-esc="doc.employee_id.contract_id.hiring_date"/>
</td>
<td>Hire Date</td>
</tr>
</tbody>
</table>
</div>
<br/>
<br/>
<br/>
<h4 style="text-align: center;">
<span>مدير إدارة الموارد البشرية</span>
</h4>
<h4 style="text-align: center;">
<span>Director of Human Resource</span>
</h4>
<h4 style="text-align: center;">
<span>
<span t-esc="env.user.company_id.hr_manager_id.name"/>
</span>
</h4>
<!--div class="row" style="font-family: 'Sakkal Majalla'!important;">
<div class="col-xs-5">
<p style="direction: ltr;">* <span>Any Alteration or erasures will void this form</span></p>
</div>
<div class="col-xs-3"/>
<div class="col-xs-4">
<p>* <span>اي قشط او تعديل يلغي هذه الشهادة</span></p>
</div>
</div-->
</div>
</div>
</t>
<div class="footer">
<div class="row text-center">
<!--<img src="/hr_custom_workflow/static/img/footer.png" style="width:100%;" class="text-center"/>-->
</div>
</div>
</t>
</template>
<record id="action_report_employee_identify_3" model="ir.actions.report">
<field name="model">employee.other.request</field>
<field name="name">Employee Identify Without Payroll</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.report_employee_identify_3</field>
<field name="report_file">employee_requests.report_employee_identify_3</field>
<field name="groups_id" eval="[(4, ref('hr.group_hr_user'))]"/>
</record>
</odoo>

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<template id="salary_confirmation">
<t t-call="web.html_container" t-translation="off">
<t t-call="hr_base.hr_layout">
<style>
@font-face {font-family: "Sakkal Majalla"; src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot"); src:
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.eot?#iefix")
format("embedded-opentype"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff2") format("woff2"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.woff") format("woff"),
url("/employee_requests/static/fonts/ce7b5754581057e6f7444e2192850cc8.ttf") format("truetype");
}
</style>
<div class="page" style="font-family:'Sakkal Majalla'!important;font-size:18pt;direction:rtl">
<t t-foreach="docs" t-as="o">
<div class="row">
<strong>
<span style="margin-right: 8%;">التاريخ :</span>
</strong>
<span style="font-size:21px;" t-esc="o.change_current_date_hijri()"/>
<br/>
<strong>
<span style="margin-right: 8%;">الموافق :</span>
</strong>
<span style="font-size:20px;" t-esc="o.date"/>
<br/>
</div>
<br/>
<div class="OutlineElement Rtl SCXW182515882 BCX2">
<h3 style="font-weight:bold;margin-bottom: 60px;text-align:center;font-family: 'Sakkal Majalla'!important;color:black;font-size: 20pt;margin-top: 0;">
<span>تثبيت راتب</span>
</h3>
</div>
<!-- <div class="row">-->
<!-- <h2 style="text-align: center;">-->
<!-- <strong>تثبيت راتب</strong>-->
<!-- <br/>-->
<!-- </h2>-->
<!-- </div>-->
<br/>
<table cellpadding="2" cellspacing="2"
class="table table-borderless"
style="width:100%;border-collapse: collapse;border-collapse:separate;border-spacing: 0 10px;"
dir="rtl">
<tr style="border: 0">
<td style="text-align:right;border:0;">
<span style="float:right;margin-right:8%">
<strong>السـادة/</strong>
<span t-esc="o.destination"/>
</span>
<span style="float:left;margin-left:8%">
<strong>المحترمين ,,</strong>
</span>
</td>
</tr>
</table>
<div class="text-center">
<p style="text-align:center;margin: 10px;">
<span>السلام عليكم ورحمة الله و بركاته ,,</span>
</p>
</div>
<br/>
<p style="text-align:justify;margin-right:8%;margin-left:8%;color:black; line-height: 1.8;">
وبهذا تفيد
<span t-esc="o.employee_id.company_id.name"/>
بأن
الأستاذ/ة
<span t-field="o.employee_id.name"/>
رقم الهوية الوطنية (
<t t-if="o.employee_id.country_id.name == 'Saudi Arabia' or o.employee_id.country_id.name == 'المملكة العربية السعودية'">
<span t-field="o.employee_id.saudi_number.saudi_id"/>
</t>
<t t-else="">
<span t-field="o.employee_id.iqama_number.iqama_id"/>
</t>
)
يعمل لدينا بوظيفة (<span t-field="o.employee_id.job_id.name"/>) من تاريخ
<span t-esc="o.employee_id.contract_id.date_start"/>
ويتقاضى/تتقاضى راتب اساسي وقدره (<span t-field="o.employee_id.contract_id.salary"/>)
وبدل سكن وقدره
(<span
t-field="o.employee_id.contract_id.house_allowance_temp"/>) وبدل نقل وقدره
(<span t-field="o.employee_id.contract_id.transport_allowance_temp"/>)، ومازال/ت على رأس
العمل حتى تاريخه ولا
<span>مانع لدينا</span>
من تحويـل راتبه إلـى حسـابه
(<span t-esc="o.employee_id.bank_account_id.acc_number"/>) لدى بنك
<span t-esc="o.employee_id.bank_code"/>
ولا يتم إلغاء هذا التحويل إلا بعد إخلاء الطرف من البنك .
</p>
<br/>
<h4 style="text-align: center;">
<strong>وتقبلوا تحياتنا،،،</strong>
</h4>
<br/>
<h4 style="text-align: center;">
<strong>إدارة الموارد البشرية</strong>
</h4>
<br/>
</t>
</div>
</t>
</t>
</template>
<record id="salary_conf_report_act" model="ir.actions.report">
<field name="model">employee.other.request</field>
<field name="name">Salary Confirmation</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">employee_requests.salary_confirmation</field>
<field name="report_file">employee_requests.salary_confirmation</field>
<field name="groups_id" eval="[(4, ref('hr.group_hr_user'))]"/>
</record>
</data>
</odoo>

View File

@ -0,0 +1,269 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="employee_effective_form_emp_rule" model="ir.rule">
<field name="name">Employee: views its forms record</field>
<field name="model_id" ref="model_employee_effective_form"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="employee_effective_form_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views forms of its subordinates</field>
<field name="model_id" ref="model_employee_effective_form"/>
<field name="domain_force">['|',('department_id.manager_id.user_id','=', user.id),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_effective_form_hr_rule" model="ir.rule">
<field name="name">Allow HR : views custody receiving records of all employees</field>
<field name="model_id" ref="model_employee_effective_form"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_effective_form_comp_rule" model="ir.rule">
<field name="name">Employee effective form company rule</field>
<field name="model_id" ref="model_employee_effective_form"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<!--##################overtime ###############################-->
<record id="employee_overtime_request_emp_rule" model="ir.rule">
<field name="name">Employee: views its overtime records</field>
<field name="model_id" ref="model_employee_overtime_request"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="employee_overtime_request_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views overtime of its subordinates</field>
<field name="model_id" ref="model_employee_overtime_request"/>
<field name="domain_force">['|',('employee_id.department_id.manager_id.user_id','=', user.id),
('employee_id.department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups" eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_overtime_request_hr_rule" model="ir.rule">
<field name="name">Allow HR : views custody receiving records of all employees</field>
<field name="model_id" ref="model_employee_overtime_request"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr_base.group_account_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_overtime_request_comp_rule" model="ir.rule">
<field name="name">Employee effective form company rule</field>
<field name="model_id" ref="model_employee_overtime_request"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<!--##################line_ids_over_time ###############################-->
<record id="employee_overtime_request_employee_rule" model="ir.rule">
<field name="name">Employee: views its overtime records</field>
<field name="model_id" ref="model_line_ids_over_time"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="employee_overtime_request_division_mgr_employee_rule" model="ir.rule">
<field name="name">Division manager: views overtime of its subordinates</field>
<field name="model_id" ref="model_line_ids_over_time"/>
<field name="domain_force">['|',('employee_id.department_id.manager_id.user_id','=', user.id),
('employee_id.department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_overtime_request_hr_employee_rule" model="ir.rule">
<field name="name">Allow HR : views custody receiving records of all employees</field>
<field name="model_id" ref="model_line_ids_over_time"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr_base.group_account_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_overtime_request_comp_employee_rule" model="ir.rule">
<field name="name">Employee effective form company rule</field>
<field name="model_id" ref="model_line_ids_over_time"/>
<field name="domain_force">['|',('employee_id.company_id','=',False),('employee_id.company_id', 'in', company_ids)]</field>
</record>
<!--##################overtime ###############################-->
<record id="employee_overtime_request_comp_rule" model="ir.rule">
<field name="name">Employee effective form company rule</field>
<field name="model_id" ref="model_employee_overtime_request"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="hr_clearance_form_emp_rule" model="ir.rule">
<field name="name">Employee: views its clearance records</field>
<field name="model_id" ref="model_hr_clearance_form"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="hr_clearance_form_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views clearances of its subordinates</field>
<field name="model_id" ref="model_hr_clearance_form"/>
<field name="domain_force">['|','|',('department_id','=', False),('department_id.manager_id.user_id','=',
user.id),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="hr_clearance_form_hr_rule" model="ir.rule">
<field name="name">Allow HR : views clearances of all employees</field>
<field name="model_id" ref="model_hr_clearance_form"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr_base.group_account_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_clearance_form_hr_rule_comp_rule" model="ir.rule">
<field name="name">Employee clearances multi company rule</field>
<field name="model_id" ref="model_hr_clearance_form"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="hr_personal_permission_emp_rule" model="ir.rule">
<field name="name">Employee: views its permission records</field>
<field name="model_id" ref="model_hr_personal_permission"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="hr_personal_permission_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views permissions of its subordinates</field>
<field name="model_id" ref="model_hr_personal_permission"/>
<field name="domain_force">['|','|',('department_id','=', False),('department_id.manager_id.user_id','=',
user.id),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="hr_personal_permission_hr_rule" model="ir.rule">
<field name="name">Allow HR : views permissions of all employees</field>
<field name="model_id" ref="model_hr_personal_permission"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr_base.group_account_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_personal_permission_comp_rule" model="ir.rule">
<field name="name">Employee personal permission company rule</field>
<field name="model_id" ref="model_hr_personal_permission"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="employee_other_request_emp_rule" model="ir.rule">
<field name="name">Employee: views its Other Request</field>
<field name="model_id" ref="model_employee_other_request"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="employee_other_request_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views Other Request of its subordinates</field>
<field name="model_id" ref="model_employee_other_request"/>
<field name="domain_force">['|','|',('department_id','=', False),('department_id.manager_id.user_id','=',
user.id),
('department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_other_requests_hr_rules" model="ir.rule">
<field name="name">Allow HR : views Other Request of all employees</field>
<field name="model_id" ref="model_employee_other_request"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_general_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<!--Department Jobs Request-->
<record id="employee_department_jobs_emp_rule" model="ir.rule">
<field name="name">Employee: views its Department Jobs Request</field>
<field name="model_id" ref="model_employee_department_jobs"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="employee_department_jobs_division_mgr1_rule" model="ir.rule">
<field name="name">Division manager1: views Department Jobs Request</field>
<field name="model_id" ref="model_employee_department_jobs"/>
<field name="domain_force">['|',('old_department_2_id.manager_id.user_id','=', user.id),
('old_department_2_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_department_jobs_division_mgr2_rule" model="ir.rule">
<field name="name">Division manager2: views Department Jobs Request</field>
<field name="model_id" ref="model_employee_department_jobs"/>
<field name="domain_force">['|',('new_department_id.manager_id.user_id','=', user.id),
('new_department_id.parent_id.manager_id.user_id','child_of', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="employee_other_request_hr_rule" model="ir.rule">
<field name="name">Allow HR : views Other Request of all employees</field>
<field name="model_id" ref="model_employee_department_jobs"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="employee_department_jobs_hr_rule_comp_rule" model="ir.rule">
<field name="name">Employee department multi company rule</field>
<field name="model_id" ref="model_employee_department_jobs"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="employee_other_request_hr_rule_comp_rule" model="ir.rule">
<field name="name">Employee other request multi company rule</field>
<field name="model_id" ref="model_employee_other_request"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,18 @@
id,name,model_id:id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_document_directory,access_document_directory,model_document_directory,base.group_user,1,0,0,0
access_employee_effective_form,access_employee_effective_form,model_employee_effective_form,base.group_user,1,1,1,1
access_employee_overtime_request,access_employee_overtime_request,model_employee_overtime_request,base.group_user,1,1,1,1
access_line_ids_over_time_emp,line.ids.over.time.emp,model_line_ids_over_time,base.group_user,1,1,1,1
access_house_allowance_advance,access_house_allowance_advance,model_house_allowance_advance,base.group_user,1,0,0,0
access_house_allowance_advance_line,access_house_allowance_advance_line,model_house_allowance_advance_line,base.group_user,1,0,0,0
access_hr_clearance_form,access_hr_clearance_form,model_hr_clearance_form,base.group_user,1,1,1,1
access_hr_clearance_form_division,access_hr_clearance_form_division,model_hr_clearance_form,hr_base.group_division_manager,1,1,1,1
access_hr_personal_permission,access_hr_personal_permission,model_hr_personal_permission,base.group_user,1,1,1,1
access_hr_job_emp,hr.job: Employee,hr.model_hr_job,base.group_user,1,1,1,0
access_employee_department_jobs_emp,employee_department_jobs_emp,model_employee_department_jobs,base.group_user,1,0,0,0
access_employee_department_jobs_hr,employee_department_jobs_hr,model_employee_department_jobs,hr.group_hr_user,1,1,1,1
access_employee_department_jobs_division,employee_department_jobs_division,model_employee_department_jobs,hr_base.group_division_manager,1,1,1,1
access_employee_department_jobs_manager,employee_department_jobs_manager,model_employee_department_jobs,hr_base.group_department_manager,1,1,1,1
access_employee_other_request_hr,employee_other_request_hr,model_employee_other_request,base.group_user,1,1,1,1
access_degree_medical_issuance_hr,degree_medical_issuance_hr,model_degree_medical_issuance,hr.group_hr_user,1,1,1,1
access_degree_medical_issuance_emp,degree_medical_issuance_emp,model_degree_medical_issuance,base.group_user,1,0,0,0
1 id name model_id:id group_id/id perm_read perm_write perm_create perm_unlink
2 access_document_directory access_document_directory model_document_directory base.group_user 1 0 0 0
3 access_employee_effective_form access_employee_effective_form model_employee_effective_form base.group_user 1 1 1 1
4 access_employee_overtime_request access_employee_overtime_request model_employee_overtime_request base.group_user 1 1 1 1
5 access_line_ids_over_time_emp line.ids.over.time.emp model_line_ids_over_time base.group_user 1 1 1 1
6 access_house_allowance_advance access_house_allowance_advance model_house_allowance_advance base.group_user 1 0 0 0
7 access_house_allowance_advance_line access_house_allowance_advance_line model_house_allowance_advance_line base.group_user 1 0 0 0
8 access_hr_clearance_form access_hr_clearance_form model_hr_clearance_form base.group_user 1 1 1 1
9 access_hr_clearance_form_division access_hr_clearance_form_division model_hr_clearance_form hr_base.group_division_manager 1 1 1 1
10 access_hr_personal_permission access_hr_personal_permission model_hr_personal_permission base.group_user 1 1 1 1
11 access_hr_job_emp hr.job: Employee hr.model_hr_job base.group_user 1 1 1 0
12 access_employee_department_jobs_emp employee_department_jobs_emp model_employee_department_jobs base.group_user 1 0 0 0
13 access_employee_department_jobs_hr employee_department_jobs_hr model_employee_department_jobs hr.group_hr_user 1 1 1 1
14 access_employee_department_jobs_division employee_department_jobs_division model_employee_department_jobs hr_base.group_division_manager 1 1 1 1
15 access_employee_department_jobs_manager employee_department_jobs_manager model_employee_department_jobs hr_base.group_department_manager 1 1 1 1
16 access_employee_other_request_hr employee_other_request_hr model_employee_other_request base.group_user 1 1 1 1
17 access_degree_medical_issuance_hr degree_medical_issuance_hr model_degree_medical_issuance hr.group_hr_user 1 1 1 1
18 access_degree_medical_issuance_emp degree_medical_issuance_emp model_degree_medical_issuance base.group_user 1 0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,22 @@
@media (min-width: 768px){
.rtl .navbar-right{
float: left !important;
}
.rtl .navbar-right .dropdown .dropdown-menu{
right: auto !important;
left: 0 !important;
}
.rtl .navbar-left{
float: right !important;
}
.rtl .navbar-left .dropdown .dropdown-menu{
left: auto !important;
right: 0 !important;
}
.navbar-nav.navbar-right:last-child{
margin-left: auto;
}
.rtl .pull-left{
float: right !important;
}
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="attendance_transaction_inherited_view" model="ir.ui.view">
<field name="name">attendance.transaction.inherit.view</field>
<field name="model">hr.attendance.transaction</field>
<field name="inherit_id" ref="attendances.employee_attendance_transactions_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='attendance']" position="after">
<group name="personal_permission">
<field name="approve_personal_permission" required="1" readonly="1"/>
<field name="personal_permission_id" readonly="1"/>
<field name="total_permission_hours" widget="float_time" readonly="1"/>
</group>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="attendance_transaction_inherited_tree">
<field name="name">attendance.transaction.tree.inherit</field>
<field name="model">hr.attendance.transaction</field>
<field name="type">tree</field>
<field name="inherit_id" ref="attendances.attendance_transaction_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//tree" position="attributes">
<attribute name="decoration-bf">approve_personal_permission==True</attribute>
</xpath>
<xpath expr="//field[@name='early_exit']" position="after">
<field name="total_permission_hours" widget="float_time"/>
<field name="approve_personal_permission" invisible="1"/>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,139 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="view_employee_form_leave_inherit_001" model="ir.ui.view">
<field name="name">hr.employee.leave.form.inherit_2</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='country_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='identification_id']" position="replace">
<group name="new_group" col="2" colspan="2">
<field name="country_id" options='{"no_open": True, "no_create": True}'
attrs="{'readonly':[('state','!=','draft')]}"/>
<!--field name="identification_id" groups="hr.group_hr_user"
attrs="{'readonly':[('state','!=','draft')]}"/-->
<field name="check_nationality" invisible="1"/>
<field name="religion" string="Religion" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="blood_type" string="Blood Type" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="is_address_home_a_company" invisible="1"/>
</group>
</xpath>
<xpath expr="//field[@name='first_hiring_date']" position="before">
<field name="date_of_employment" string="First Employment Date" attrs="{'readonly':[('state','!=','draft')]}" invisible="1"/>
</xpath>
<xpath expr="//page[@name='personal_information']/group/group[2]" position="after">
<group name="passport_information" string="Passport or ID Information for employee" col="4"
colspan="4">
<field name="saudi_number" string="Saudi ID"
domain="[('employee_ref','=',id),('document_type','=','saudi')]"
context="{'default_employee_ref':id,'default_document_type':'saudi'}"
attrs="{'invisible':[('check_nationality','=',False)],'required':[('check_nationality','=',True)],'readonly':[('state','!=','draft')]}"/>
<field name="date_issuance_saudi_id" string="Date of issue" widget="date"
attrs="{'invisible':[('check_nationality','=',False)],'required':[('check_nationality','=',True)]}"/>
<field name="expiration_date_saudi_id" string="Expiration date" widget="date"
attrs="{'invisible':[('check_nationality','=',False)],'required':[('check_nationality','=',True)]}"/>
<field name="place_issuance_saudi_id" string="Place of issue"
attrs="{'invisible':[('check_nationality','=',False)]}"/>
<field name="passport_id" domain="[('employee_ref','=',id),('document_type','=','passport')]"
attrs="{'readonly':[('state','!=','draft')]}"
context="{'default_employee_ref':id,'default_document_type':'passport'}"/>
<field name="iqama_number" string="Identity No."
domain="[('employee_ref','=',id),('document_type','=','Iqama')]"
attrs="{'invisible':[('check_nationality','=',True)],'required':[('check_nationality','=',False)],'readonly':[('state','!=','draft')]}"
context="{'default_employee_ref':id,'default_document_type':'Iqama'}"/>
<field name="date_issuance_passport" string="Passport Issue Date" widget="date"
/>
<field name="emp_iqama_job" string="Identity Job"
attrs="{'invisible':[('check_nationality','=',True)]}"/>
<field name="expiration_date_passport" string="Passport Expiry Date" widget="date"
/>
<field name="iqama_expiy_date" string="Identity Expiry Date"
attrs="{'invisible':[('check_nationality','=',True)],'required':[('check_nationality','=',False)]}"/>
<field name="place_issuance_passport" string="Place Issue Passport"
attrs="{'invisible':[('check_nationality','=',True)]}"/>
<field name="iqama_creat_date" string="Identity Issue Date"
attrs="{'invisible':[('check_nationality','=',True)],'required':[('check_nationality','=',False)]}"/>
</group>
</xpath>
<xpath expr="//field[@name='iqama_creat_date']" position="after">
<field name="own_license" string="Own a license" attrs="{'readonly':[('state','!=','draft')]}"/>
</xpath>
<xpath expr="//field[@name='own_license']" position="after">
<field name="license_number_id" string="License number"
domain="[('employee_ref','=',id),('document_type','=','license')]"
attrs="{'invisible':[('own_license','=',False)],'readonly':[('state','!=','draft')]}"
context="{'default_employee_ref':id,'default_document_type':'license'}"/>
<field name="expiry_license" string="Expiry date of license"
attrs="{'invisible':[('own_license','=',False)]}" widget="date"/>
</xpath>
<xpath expr="//group[@name='work_permit']" position="replace">
</xpath>
<xpath expr="//page[@name='hr_settings']" position="after">
<page name="medical_insurance" string="Accommodation and Medical insurance">
<group>
<group attrs="{'invisible':[('check_nationality','=',True)]}">
<separator string="Guaranty" />
<field name="on_company_guarantee" string="On company guarantee?"
attrs="{'readonly':[('state','!=','draft')]}"/>
<!--field name="validity_transfer_sponsorship" string="validity transfer of sponsorship"
attrs="{'readonly':[('state','!=','draft')],'invisible':[('on_company_guarantee','=',False)]}"/-->
<field name="first_entry_into_saudi_arabia"
attrs="{'readonly':[('state','!=','draft')],'invisible':[('on_company_guarantee','=',False)]}"
string="First date entry into Saudi Arabia"/>
</group>
<group>
<separator string="Insurances"
attrs="{'invisible':[('on_company_guarantee','=',False)]}"/>
<field name="residency_number" string="Insurances Number"
attrs="{'readonly':[('state','!=','draft')],'invisible':[('on_company_guarantee','=',False)]}"/>
<field name="date_issuance_residence" string="Date of issuance Insurances"
widget="date"
attrs="{'readonly':[('state','!=','draft')],'invisible':[('on_company_guarantee','=',False)]}"/>
<!--field name="expiration_date_residence" string="Expiration date of residence"
widget="date" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="place_issuance_residence" string="Place issuance residence"
attrs="{'readonly':[('state','!=','draft')]}"/-->
<!--field name="number_of_visa" string="Number of Visa"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="medical_exam_check"
attrs="{'invisible':[('check_nationality','=',True)],'required':[('check_nationality','=',False)],'readonly':[('state','!=','draft')]}"/-->
</group>
</group>
<group>
<group>
<separator string="Medical Insurance"/>
<field name="medical_insurance" string="Medical insurance"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="degree_medical_insurance" string="Degree of medical insurance"
attrs="{'required':[('medical_insurance','=', True)],'readonly':[('state','!=','draft')]}"/>
<field name="medical_insurance_number" string="Medical insurance number"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="copy_examination_file"
string="Copy of examination file"
domain="[('employee_ref','=',id),('document_type','=','medical_Examination')]"
attrs="{'readonly':[('state','!=','draft')]}"
context="{'default_employee_ref':id,'default_document_type':'medical_Examination'}"/>
<!--field name="date_of_expiry" string="Date of expiry" widget="date"/-->
</group>
</group>
</page>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="employee_department_jobs_action" model="ir.actions.act_window">
<field name="name">Employee Department and Jobs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.department.jobs</field>
<field name="view_mode">tree,form,calendar</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Employee Departments and jobs
</p>
</field>
</record>
<record model="ir.ui.view" id="view_department_jobs_calendar">
<field name="name">employee.department.jobs.calendar</field>
<field name="model">employee.department.jobs</field>
<field name="arch" type="xml">
<calendar string="Employee Department and Jobs" date_start="date" color="date">
<field name="date" type="measure"/>
</calendar>
</field>
</record>
<record id="employee_department_jobs_form_view" model="ir.ui.view">
<field name="name">employee.department.jobs.form.view</field>
<field name="model">employee.department.jobs</field>
<field name="arch" type="xml">
<form string="Employee Departments and jobs">
<header>
<button name="confirm" string="Department Manager" class="oe_highlight" states="draft" type="object"
groups="hr.group_hr_user,hr_base.group_division_manager"/>
<button name="hr_officer" string="HR Officer" class="oe_highlight" states="confirm" type="object"
groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" states="confirm" type="object"
groups="hr.group_hr_user"/>
<button name="confirm2" string="Department Manager2" class="oe_highlight" states="hr_officer" type="object"
groups="hr.group_hr_user,hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" states="hr_officer" type="object"
groups="hr.group_hr_user,hr_base.group_division_manager"/>
<button name="hr_manager" string="HR Manager" class="oe_highlight" states="confirm2" type="object"
groups="hr.group_hr_manager"/>
<button name="refused" string="Refused" class="oe_highlight" states="confirm2" type="object"
groups="hr.group_hr_manager"/>
<button name="approved" string="Approved" class="oe_highlight" states="hr_manager" type="object"
groups="hr_base.group_executive_manager,hr_base.group_general_manager"/>
<button name="refused" string="Refused" class="oe_highlight" states="hr_manager" type="object"
groups="hr_base.group_executive_manager,hr_base.group_general_manager"/>
<button name="draft" string="Re-draft" class="oe_highlight" states="approved,refused" type="object"
groups="hr.group_hr_manager" confirm="Are you sure to Reset To Draft This Record?"/>
<button name="print_report" string="Print Report" class="oe_highlight"
attrs="{'invisible':['|',('state','!=','approved'),('promotion_type','=', 'job')]}" type="object"/>
<field name="state" widget="statusbar" statusbar_colors="{'KEY_IS_STATE':'VALUE_IS_COLOR'}"/>
</header>
<sheet>
<group>
<field name="employee_id" string="Employee Name" required="1"
attrs="{'readonly':[('state','!=','draft')]}" colspan="4"/>
</group>
<group>
<group>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="promotion_type" string="Promotion type" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="new_department_id" string="New Department"
attrs="{'readonly':[('state','!=','draft')],
'invisible':[('promotion_type','not in',['department','both'])],
'required':[('promotion_type','in',['department','both'])]}"/>
<field name="new_manager_id" string="New Manager" readonly="1" force_save="1"
attrs="{'invisible':[('promotion_type','not in',['department','both'])]}"/>
<field name="new_job_id" string="New job"
attrs="{'readonly':[('state','!=','draft')],
'invisible':[('promotion_type','not in',['job','both'])],
'required':[('promotion_type','in',['job','both'])]}"/>
<field name="date" string="Procedure Date" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group>
<field name="last_record" string="Is Last Record?" readonly="1"/>
<!--field name="old_department_id" string="Old department" invisible="1"/-->
<field name="old_department_2_id" string="Old department" readonly="1" force_save="1"/>
<field name="old_manager_id" string="Old Manager" readonly="1" force_save="1"/>
<!--field name="old_job_id" string="Old Job" invisible="1"/-->
<field name="old_job_2_id" string="Old Job" readonly="1" force_save="1"/>
<field name="old_job_date" string="Old Job Date" readonly="1" force_save="1"
attrs="{'invisible':[('promotion_type','not in',['job','both'])]}"/>
<label for="service_year" string="Duration"/>
<div>
<field name="service_year" readonly="1" force_save="1" class="oe_inline" />Years
<field name="service_month" readonly="1" force_save="1" class="oe_inline" />Months
<field name="service_day" readonly="1" force_save="1" class="oe_inline" />Days
</div>
</group>
</group>
<separator string="Comment"/>
<field name="comment" string="Comment" attrs="{'readonly':[('state','!=','draft')]}"/>
</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"/>
</div>
</form>
</field>
</record>
<record id="employee_department_jobs_tree_view" model="ir.ui.view">
<field name="name">employee.department.jobs.tree.view</field>
<field name="model">employee.department.jobs</field>
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'" string="Employee Departments and jobs">
<field name="employee_id" string="Employee name"/>
<field name="new_department_id" string="New department"/>
<field name="new_job_id" string="New Job"/>
<field name="date" string="Date"/>
<field name="state" string="State"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,107 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="employee_request_list_action">
<field name="name">Employee Effective Form</field>
<field name="res_model">employee.effective.form</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<record model="ir.ui.view" id="view_request_effective_calendar">
<field name="name">employee.effective.form.calendar</field>
<field name="model">employee.effective.form</field>
<field name="arch" type="xml">
<calendar string="Employee Effective Form" date_start="effective_form_date" color="effective_form_date">
<field name="effective_form_date" type="measure"/>
</calendar>
</field>
</record>
<record model="ir.ui.view" id="employee_request_effective_form_view">
<field name="name">Employee Request Effective</field>
<field name="model">employee.effective.form</field>
<field name="arch" type="xml">
<form>
<header>
<button name="submit" string="Submit" class="oe_highlight" type="object"
states="draft"
groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager Approve" class="oe_highlight" type="object"
states="submit"
groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="submit"
groups="hr_base.group_division_manager"/>
<button name="hr_manager" string="HR M Approve" class="oe_highlight" type="object"
states="direct_manager"
groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager"
groups="hr.group_hr_user"/>
<button name="done" string="done" class="oe_highlight" type="object"
states="hr_manager"
groups="hr_base.group_general_manager,hr_base.group_executive_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="hr_manager"
groups="hr_base.group_general_manager,hr_base.group_executive_manager"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="refused,done"
groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="from_hr" string="Another Employee" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee"
attrs="{'readonly': ['|',('from_hr','=',False),('state','!=','draft')],'required':True}"/>
<field name="contract_id" string="Contract" readonly="True" groups="hr.group_hr_user"/>
<field name="job_id" string="Job Name" readonly="True"/>
<field name="department_id" string="Department" readonly="True"/>
<!--field name="employee_salary" string="Salary" readonly="True"
attrs="{'invisible':[('effective_form_type','=','return_from_leave')]}"/>
<field name="employee_house_all" string="House expends " readonly="True"
attrs="{'invisible':[('effective_form_type','=','return_from_leave')]}"/>
<field name="total_salary" string="Total Salary" readonly="True"
attrs="{'invisible':[('effective_form_type','=','return_from_leave')]}"/-->
</group>
<group>
<field name="company_id" groups="base.group_multi_company" attrs="{'readonly': [('state','!=', 'draft')]}"/>
<field name="effective_form_type" string="Form Type" readonly="True" invisible="1"/>
<field name="contract_start" string="Contract Start Date" />
<field name="effective_form_date" string="Effective Form Date" required="True"
attrs="{'readonly':[('state','not in',('draft'))]}"/>
</group>
<group>
<field name="remarks" string="Remarks" attrs="{'readonly':[('state','!=','draft')]}" groups="hr.group_hr_user"/>
</group>
</group>
</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"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="employee_request_effective_tree_view">
<field name="name">Employee Request Effective</field>
<field name="model">employee.effective.form</field>
<field name="arch" type="xml">
<tree decoration-danger="state == 'refused'" decoration-info="state == 'draft'" string="Employee Request Effective">
<field name="employee_id" string="Employee"/>
<field name="department_id" string="Department"/>
<field name="contract_start" string="Contract Start Date"/>
<field name="effective_form_date" string="Effective Form Date"/>
<field name="state" string="Status"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,139 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="employee_overtime_request_list_action">
<field name="name">Employee OverTime Request</field>
<field name="res_model">employee.overtime.request</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<record model="ir.ui.view" id="view_overtime_calendar">
<field name="name">employee.overtime.request.calendar</field>
<field name="model">employee.overtime.request</field>
<field name="arch" type="xml">
<calendar string="Employee Overtime Request" date_start="request_date" color="request_date">
<field name="request_date" type="measure"/>
</calendar>
</field>
</record>
<record model="ir.ui.view" id="employee_overtime_request_form_view">
<field name="name">Employee Overtime Request</field>
<field name="model">employee.overtime.request</field>
<field name="arch" type="xml">
<form>
<header>
<button name="submit" string="Submit" class="oe_highlight" type="object"
states="draft" groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager Approve" class="oe_highlight" type="object"
states="submit" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="submit" groups="hr_base.group_division_manager"/>
<button name="financial_manager" string="Department Manager" class="oe_highlight" type="object"
states="direct_manager" groups="hr_base.group_department_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager" groups="hr_base.group_department_manager"/>
<button name="hr_aaproval" string="HR Approval" class="oe_highlight" type="object"
states="financial_manager" groups="hr.group_hr_user, hr.group_hr_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="financial_manager" groups="hr.group_hr_user, hr.group_hr_manager"/>
<button name="executive_office" string="Executive Approval" class="oe_highlight" type="object"
groups="hr_base.group_general_manager,hr_base.group_executive_manager"
attrs="{'invisible':['|',('state','!=','hr_aaproval'),('exception','!=',True)]}"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
groups="hr_base.group_general_manager,hr_base.group_executive_manager"
attrs="{'invisible':['|',('state','!=','hr_aaproval'),('exception','!=',True)]}"/>
<button name="validated" string="Finance Approval" class="oe_highlight" type="object"
groups="hr_base.group_account_manager"
states="executive_office"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="executive_office" groups="hr_base.group_account_manager"/>
<button name="re_draft" string="RE-Draft" class="oe_highlight" type="object"
states="refused,validated"
groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="transfer_type" attrs="{'readonly':[('state','!=','financial_manager')], 'required': [('state', '=', 'financial_manager')]}"/>
<field name="employee_id" string="Responsible " required="1" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="date_from" string="Date From"
attrs="{'readonly':[('state','not in',('financial_manager','draft','submit'))], 'required': [('state', 'in', ('financial_manager','draft','submit'))]}"/>
<field name="date_to" string="Date To"
attrs="{'readonly':[('state','not in',('financial_manager','draft','submit'))], 'required': [('state', 'in', ('financial_manager','draft','submit'))]}"/>
<field name="benefits_discounts"
attrs="{'invisible':[('transfer_type','!=','payroll')], 'readonly':[('state','!=','financial_manager')], 'required': [('transfer_type', '=', 'payroll'),('state','=','financial_manager')]}"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="request_date" string="Request Date" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="department_id" string="Department" attrs="{'readonly':[('state','not in',('submit','draft'))]}"/>
<field name="overtime_plase" string="Overtime Plase" attrs="{'readonly':[('state','!=','draft')]}" required="1"/>
<field name="reason" string="Reason" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="exception" groups="hr_base.group_executive_manager,hr.group_hr_user" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="account_id" string="Account"
attrs="{'invisible':['|',('transfer_type','!=','accounting'),('state','!=','hr_aaproval')], 'readonly':[('state','!=','hr_aaproval')], 'required': [('state', '=', 'hr_aaproval'),('transfer_type','=','accounting')]}"/>
<field name="journal_id" string="Journal"
attrs="{'invisible':['|',('transfer_type','!=','accounting'),('state','!=','hr_aaproval')], 'readonly':[('state','!=','hr_aaproval')], 'required': [('state', '=', 'hr_aaproval'),('transfer_type','=','accounting')]}"/>
</group>
</group>
<separator string="Employees Over Time"/>
<field name="line_ids_over_time" context="{'account_id': account_id, 'journal_id': journal_id}" force_save="1"
attrs="{'readonly':[('state','not in',('submit','draft'))], 'required': [('state', '=', 'hr_aaproval')]}">
<tree string="Employee Over Time" editable="bottom">
<field name="employee_id"/>
<field name="transfer_type" invisible='1' string="Transfer Type"/>
<field name="account_id" string="Account" groups="hr_base.group_account_manager" force_save="1" readonly="1"
attrs="{'invisible':[('transfer_type','!=','accounting')]}"/>
<field name="journal_id" string="Journal" groups="hr_base.group_account_manager" force_save="1" readonly="1"
attrs="{'invisible':[('transfer_type','!=','accounting')]}"/>
<!--field name="calculate_from_total" groups="hr.group_hr_user"/-->
<field name="exception" readonly="1" invisible='1'/>
<field name="remaining_hours" force_save="1" readonly="1"/>
<field name="max_hours" force_save="1" readonly="1"/>
<field name="over_time_workdays_hours" />
<field name="over_time_vacation_hours"/>
<field name="daily_hourly_rate" groups="hr_base.group_account_manager,hr.group_hr_user"/>
<field name="holiday_hourly_rate" groups="hr_base.group_account_manager,hr.group_hr_user"/>
<field name="price_hour" groups="hr_base.group_account_manager,hr.group_hr_user"/>
</tree>
</field>
</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"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="employee_overtime_request_tree_view">
<field name="name">Employee Overtime Request</field>
<field name="model">employee.overtime.request</field>
<field name="arch" type="xml">
<tree decoration-danger="state == 'refused'" decoration-info="state == 'draft'" string="Employee Overtime Request">
<field name="employee_id" string="Responsible"/>
<field name="department_id" string="Department"/>
<field name="request_date" string="Request Date"/>
<field name="date_from" string="Date From"/>
<field name="date_to" string="Date To"/>
<field name="state" string="Status"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<odoo>
<data>
<!-- menu item of employees request-->
<menuitem name="Employees Requests" id="employee_request_menu_item"
parent="hr.menu_hr_root" sequence="2"
groups="base.group_user"/>
<menuitem name="Employee Effective Form" id="employee_effective_form"
parent="employee_request_menu_item" action="employee_request_list_action" sequence="1"/>
<menuitem name="Employee OverTime Request" id="employee_overtime_request_menu_item"
parent="employee_request_menu_item" action="employee_overtime_request_list_action" sequence="2"/>
<!--menuitem name="Houes Allowance Advanced" id="employee_house_allowance_advance_menu_item"
parent="employee_request_menu_item"
action="employee_allowance_advance_list_action"/-->
<menuitem name="Employee Clearance Form" id="employee_clearance_form"
parent="employee_request_menu_item" action="employee_clearance_form_action" sequence="3"/>
<menuitem name="Personal Permissions" id="employee_personal_permission_menu_item"
parent="employee_request_menu_item"
action="employee_personal_permission_action" sequence="3"/>
<!-- Employee Departments and jobs -->
<menuitem name="Employee Department and jobs" id="employee_department_jobs_menu_item"
parent="employee_request_menu_item" action="employee_department_jobs_action" sequence="4"
groups="hr.group_hr_user,hr_base.group_executive_manager,hr_base.group_general_manager,hr_base.group_division_manager,base.group_user"/>
<!--Employee Other Request -->
<menuitem name="Employee Other Request" id="employee_other_request_menu_item"
parent="employee_request_menu_item" action="employee_other_request_action" sequence="5"/>
</data>
</odoo>

View File

@ -0,0 +1,102 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="employee_allowance_advance_list_action">
<field name="name">Employee allowance advance</field>
<field name="res_model">house.allowance.advance</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.view" id="employee_house_allowance_advance_form_view">
<field name="name">Employee allowance advance</field>
<field name="model">house.allowance.advance</field>
<field name="arch" type="xml">
<form>
<header>
<button name="send" string="submit" class="oe_highlight" type="object"
states="draft"/>
<button name="hr_special_Approval" string="HR Specialist Aproval" class="oe_highlight"
type="object"
states="send"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="send"/>
<button name="financial_manager" string="Fnicial Manager Approval" class="oe_highlight"
type="object"
states="hr_manager_approved"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="hr_manager_approved"/>
<button name="hr_manager_approved" string="HR Manager Approval" class="oe_highlight"
type="object"
states="hr_special_Approval"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="hr_special_Approval"/>
<button name="approve_manager" string="Approval Manager" class="oe_highlight" type="object"
states="financial_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="financial_manager"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="refused"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="from_hr_department" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee"
attrs="{'readonly':[('from_hr_department' , '=' , False)]}"/>
<field name="job_id" string="Job Name" readonly="1"/>
<field name="department_id" string="Department" readonly="1"/>
<field name="contract_id" string="Contract"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group>
<field name="amount" string="Amount"
attrs="{'required':True,'readonly':[('state' , '!=' , 'draft')]}"/>
<field name="start_date" string="Start Date"/>
<field name="date" string="End Date"/>
<field name="duration" string="Duration"
attrs="{'required':True,'readonly':[('state' , '!=' , 'draft')]}"/>
<button name="generate installment" string="Generate Installment" class="oe_highlight"/>
</group>
</group>
<notebook>
<page string="installments" name="installment">
<field name="house_allowance_advance_line_ids"
attrs="{'readonly':[('state','!=','draft')]}">
<tree editable="bottom">
<field name="amount_id" string="Amount"/>
<field name="date" string="Start Date"/>
</tree>
</field>
</page>
<page string="Account Information" name="accounting_info">
<group></group>
<group>
<field name="account_move_id" string="Journal Entry"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="employee_house_allowance_advance_tree_view">
<field name="name">Employee allowance advance</field>
<field name="model">house.allowance.advance</field>
<field name="arch" type="xml">
<tree>
<field name="employee_id" string="Employee"/>
<field name="department_id" string="Department" required="True"/>
<field name="job_id" string="Job Name" required="True"/>
<field name="contract_id" string="Contract" required="True"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,168 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="employee_clearance_form_action">
<field name="name">Employee Clearance Form</field>
<field name="res_model">hr.clearance.form</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<record model="ir.ui.view" id="view_clearance_calendar">
<field name="name">hr.clearance.form.calendar</field>
<field name="model">hr.clearance.form</field>
<field name="arch" type="xml">
<calendar string="Employee Clearance Form" date_start="date" color="date">
<field name="date" type="measure"/>
</calendar>
</field>
</record>
<record model="ir.ui.view" id="employee_clearance_form_form_view">
<field name="name">Employee Clearance Form</field>
<field name="model">hr.clearance.form</field>
<field name="arch" type="xml">
<form>
<header>
<button name="submit" string="Submit" class="oe_highlight" type="object" states="draft" />
<button name="direct_manager" string="Direct Manager" class="oe_highlight" type="object"
states="submit" groups="hr_base.group_division_manager,hr_base.group_department_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
states="submit" groups="hr_base.group_division_manager,hr_base.group_department_manager"/>
<button name="info_system" string="IT Department" class="oe_highlight" type="object"
states="direct_manager" groups="hr_base.group_IT_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
states="direct_manager" groups="hr_base.group_IT_manager"/>
<button name="admin_manager" string="Admin Affairs" class="oe_highlight" type="object"
states="info_system" groups="hr.group_hr_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
states="info_system" groups="hr.group_hr_manager"/>
<button name="wait" string="Finance Approvals" class="oe_highlight" type="object"
states="admin_manager" groups="hr_base.group_account_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
states="admin_manager" groups="hr_base.group_account_manager"/>
<button name="done" string="HR Manager" class="oe_highlight" type="object"
states="wait" groups="hr_base.group_executive_manager,hr.group_hr_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
states="wait" groups="hr_base.group_executive_manager,hr.group_hr_manager"/>
<button name="draft" string="RE-Draft" class="oe_highlight" type="object"
states="refuse,done" groups="hr.group_hr_manager" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="from_hr_department" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee Name"
attrs="{'readonly':['|',('state','!=','draft'),('from_hr_department','!=',True)],'required':[('from_hr_department','=',True)]}"/>
<field name="date" string="Date Request" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="date_deliver_work" string="Delivering Work Date" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group name="employee_info">
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="department_id" string="Department" readonly="1"/>
<field name="job_id" string="Job Title" readonly="1"/>
<field name="clearance_type" string="Clearance Type" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</group>
<group>
<!--<group>-->
<!--<field name="leave_request_id" string="Leave Request" attrs="{'required':[('clearance_type','=','vacation')],'readonly':[('state','!=','draft')]}"/>-->
<!--<field name="start_of_vacation" string="Start of Vacation" attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!--<field name="end_of_vacation" string="End of vacation" attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!--</group>-->
</group>
<group>
<field name="work_delivered" string="Reason Of Clearance" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group>
<group>
<!--separator string="Approval Comments"/>
<br/>
<field name="super_mg" string="Approval/rejection of direct manager"
attrs="{'required':[('state','in',['submit'])],'readonly':[('state','not in',['submit'])]}"/>
<field name="super_refuse_cause" string="Refuse Cause"
attrs="{'required':[('state','in',['submit'])],'readonly':[('state','not in',['submit'])]}"/>
<field name="it_mg" string="Approval/rejection IT Manager"
attrs="{'required':[('state','in',['direct_manager'])],'readonly':[('state','not in',['direct_manager'])]}"/>
<field name="it_refuse_cause" string="IT Manager Refusal Cause"
attrs="{'required':[('state','in',['direct_manager'])],'readonly':[('state','not in',['direct_manager'])]}"/-->
<separator string="Approval Clearance Bank"/>
<br/>
<!-- <field name="bank_attachment_id" string="Bank Attach" widget="many2many_binary" class="oe_inline"-->
<!-- attrs="{'required':[('state','in',['wait'])],'readonly':[('state','not in',('wait'))]}"/>-->
<!-- <field name="bank_comments" string="Bank Resons" -->
<!-- attrs="{'required':[('state','in',['wait'])],'readonly':[('state','not in',('wait'))]}"/>-->
<field name="bank_attachment_id" string="Bank Attach" widget="many2many_binary" class="oe_inline"
attrs="{'required':[('state','in',['wait']),('clearance_type','!=','vacation')],'readonly':[('state','not in',('wait','admin_manager'))]}"/>
<field name="bank_comments" string="Bank Reasons"
attrs="{'required':[('state','in',['wait']),('clearance_type','!=','vacation')],'readonly':[('state','not in',('wait'))]}"/>
</group>
<!--group>
<separator string="Approval Comments"/>
<br/>
<field name="direct_mg" string="Approval/rejection of Administration"
attrs="{'required':[('state','in',['info_system'])],'readonly':[('state','not in',['info_system'])]}"/>
<field name="direct_refuse_cause" string="Refuse Cause"
attrs="{'required':[('state','in',['info_system'])],'readonly':[('state','not in',['info_system'])]}"/>
<field name="hr_mg" string="Approval/rejection HR Manager"
attrs="{'required':[('state','in',['wait'])],'readonly':[('state','not in',['wait'])]}"/>
<field name="hr_refuse_cause" string="HR Manager Refusal Cause"
attrs="{'required':[('state','in',['wait'])],'readonly':[('state','not in',['wait'])]}"/>
</group-->
</group>
</sheet>
<!--Discuss widgets for history and communication -->
<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"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="employee_clearance_form_tree_view">
<field name="name">Employee Clearance Form</field>
<field name="model">hr.clearance.form</field>
<field name="arch" type="xml">
<tree decoration-danger="state == 'refuse'" decoration-info="state == 'draft'" string="Employee Clearance Form">
<field name="employee_id" string="Employee Name"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job Title"/>
<field name="clearance_type" string="Clearance Type" required="1"/>
<field name="state" string="state"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,126 @@
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="employee_personal_permission_action">
<field name="name">Employee permission</field>
<field name="res_model">hr.personal.permission</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<record model="ir.ui.view" id="view_permission_calendar">
<field name="name">hr.personal.permission.calendar</field>
<field name="model">hr.personal.permission</field>
<field name="arch" type="xml">
<calendar string="Employee permission" date_start="date" color="date">
<field name="date" type="measure"/>
</calendar>
</field>
</record>
<record model="ir.ui.view" id="employee_personal_permission_form_view">
<field name="name">employee personal permission</field>
<field name="model">hr.personal.permission</field>
<field name="arch" type="xml">
<form>
<header>
<button name="send" string="Submit" class="oe_highlight" type="object"
states="draft" groups="base.group_user"/>
<button name="direct_manager" string="Direct Manager Approve" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="send" groups="hr_base.group_division_manager"/>
<button name="approve" string="HR Approve" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="direct_manager" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="approve" groups="hr.group_hr_user"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="refused" groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group string="Permission Info">
<field name="date" string="Date Request"
attrs="{'readonly':[('state','!=','draft')],'required':1}"/>
<field name="date_from" string="Date From"
attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="date_to" string="Date To"
attrs="{'readonly':[('state' , '!=' , 'draft')],'required':1}"/>
<field name="duration" string="Duration" attrs="{'readonly':1}" widget="float_time"/>
<field name="balance" string="Permission Limit" readonly="1" widget="float_time"/>
<field name="permission_number" force_save="True" string="Permission Per Month" widget="float_time"/>
<field name="type_exit" string="Type Exit"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group string="Employee Info">
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<field name="from_hr_department" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee"
attrs="{'readonly': ['|',('from_hr_department','=',False),('state','!=','draft')],'required':True}"/>
<field name="employee_no" string="Employee No" readonly="1"/>
<field name="job_id" string="Job Title" readonly="1"/>
<field name="department_id" string="Department" readonly="1"/>
</group>
</group>
<group>
<field name="mission_purpose" string="Reasons"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<!--notebook>
<page string="Attachments" name="attachments">
<field name="attach_ids" string="Attachments"
attrs="{'readonly':[('state','!=','draft')]}">
<tree editable="bottom">
<field name="name" string="attachment Name"/>
<field name="datas" string="file content"/>
</tree>
</field>
</page>
<page string="Refusal Causes" name="refusal_causes">
<field name="refuse_cause" placeholder="Refuse Cause .........."
attrs="{'readonly':[('state','!=','draft')]}"/>
</page>
<page string="Information" name="information">
<group>
<field name="approved_by" string="Approved By"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="refused_by" string="Refused By"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</page>
</notebook-->
</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"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="employee_personal_permission_tree_view">
<field name="name">Employee personal permission</field>
<field name="model">hr.personal.permission</field>
<field name="arch" type="xml">
<tree decoration-danger="state == 'refused'" decoration-info="state == 'draft'" string="Employee personal permission">
<!--field name="date" string="Date Request"/-->
<field name="employee_id" string="Employee"/>
<!--field name="employee_no" string="Employee No"/-->
<field name="date_from" string="Date From"/>
<field name="date_to" string="Date To"/>
<field name="duration" string="Duration"/>
<field name="state" string="Status"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="employee_other_request_action" model="ir.actions.act_window">
<field name="name">Employee Other Request</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.other.request</field>
<field name="view_mode">tree,form,calendar</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Employee Other Request
</p>
</field>
</record>
<record model="ir.ui.view" id="view_employee_other_request_calendar">
<field name="name">employee.other.request.calendar</field>
<field name="model">employee.other.request</field>
<field name="arch" type="xml">
<calendar string="Employee Other Request" date_start="date" color="date">
<field name="date" type="measure"/>
</calendar>
</field>
</record>
<record id="employee_other_request_form_view" model="ir.ui.view">
<field name="name">employee.other.request.form.view</field>
<field name="model">employee.other.request</field>
<field name="arch" type="xml">
<form string="Employee Other Request">
<header>
<button name="submit" string="Submit" class="oe_highlight" states="draft" type="object"/>
<button name="confirm" string="Direct Manager" class="oe_highlight" states="submit"
type="object"
groups="hr_base.group_division_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" states="submit" type="object"
groups="hr_base.group_division_manager"/>
<button name="approved" string="HR Manager" class="oe_highlight" states="confirm" type="object"
groups="hr_base.group_executive_manager,hr.group_hr_user"/>
<button name="refuse" string="Refuse" class="oe_highlight" states="confirm,approved"
type="object"
groups="hr_base.group_executive_manager,hr.group_hr_user"/>
<button name="draft" string="Re-draft" class="oe_highlight" states="refuse" type="object"
groups="hr.group_hr_user,hr_base.group_division_manager"
confirm="Are you sure to Reset To Draft This Record?"/>
<button name="print_with_details" string="Print With Details" type="object" id="with_details"
attrs="{'invisible': ['|','|',('request_type', '!=', 'salary_define'),('state', '!=', 'approved'),
('print_type', '!=', 'detail')]}"
class="oe_highlight" groups="base.group_user"/>
<button name="print_with_details2" string="Print Without Details" type="object"
id="with_details2"
attrs="{'invisible': ['|','|',('request_type', '!=', 'salary_define'),('state', '!=', 'approved'),
('print_type', '!=', 'no_detail')]}"
class="oe_highlight" groups="base.group_user"/>
<button name="print_with_details3" string="Print Without Salary" type="object"
id="with_details2"
attrs="{'invisible': ['|','|',('request_type', '!=', 'salary_define'),('state', '!=', 'approved'),
('print_type', '!=', 'no_salary')]}"/>
<button name="print_salary_confirmation" string="Print Salary Confirmation" type="object"
id="with_details2"
attrs="{'invisible': ['|',('request_type', '!=', 'salary_fixing'),('state', '!=', 'approved')]}"
class="oe_highlight" groups="base.group_user"/>
<field name="state" widget="statusbar" statusbar_colors="{'KEY_IS_STATE':'VALUE_IS_COLOR'}"/>
</header>
<sheet>
<group>
<group>
<field name="from_hr" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee Name"
attrs="{'readonly': ['|',('from_hr','=',False),('state','!=','draft')],'required':True}"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job"/>
<!--field name="type_contract" string="Type Of Contract" /-->
<!--<field name="salary_attachment" string="Salary Attachment" widget="many2many_binary" class="oe_inline"-->
<!--attrs="{'invisible': ['|',('type_contract', '=', 'self_employment'),('state', 'not in', ('confirm','approved'))],-->
<!--'readonly': [('state', '!=', 'confirm')]}"/>-->
<field name="contract_statuss" string="Contract Status"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company"
attrs="{'readonly': [('state','!=', 'draft')]}"/>
<field name="date" string="Date Request" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="request_type" string="Request type" required="1"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="create_insurance_request"
attrs="{'invisible':[('request_type','!=','dependent')]}"/>
<field name="parent_request_id" attrs="{'invisible':['|',('parent_request_id','=','False'),
('request_type','!=','insurance')]}" readonly="1"/>
<field name="destination" attrs="{'invisible': [('request_type', '!=', 'salary_define')], 'required': [('request_type', '=', 'salary_define')],
'readonly': [('state', '!=', 'draft')]}"/>
<field name="print_type" attrs="{'invisible': [('request_type', '!=', 'salary_define')], 'required': [('request_type', '=', 'salary_define')],
'readonly': [('state', '!=', 'draft')]}"/>
<!--field name="new_department_id" string="New department"
attrs="{'readonly':[('state','!=','draft')],
'invisible':[('request_type','not in',['department','both'])],
'required':[('request_type','in',['department','both'])]}"/>
<field name="new_job_id" string="New job"
attrs="{'readonly':[('state','!=','draft')],
'invisible':[('request_type','not in',['job','both'])],
'required':[('request_type','in',['job','both'])]}"/-->
</group>
</group>
<separator string="Comment"/>
<field name="comment" string="Comment" attrs="{'readonly':[('state','!=','draft')]}"/>
<separator string="Dependants" attrs="{'invisible':[('request_type','!=','dependent')]}"/>
<field name="employee_dependant"
attrs="{'invisible':[('request_type','!=','dependent')],'readonly':[('state','!=','draft')]}">
<tree string="Employee Dependants" editable="bottom">
<field name="name" required="1"/>
<field name="age" required="1"/>
<field name="gender" required="1"/>
<field name="relation" required="1"/>
<field name="passport_no" required="1"/>
<field name="nationality" string="Nationality" required="1"/>
<field name="birthday" string="BirthDay" required="1"/>
<field name="attachment" string="Attachment" class="oe_inline"
widget="many2many_binary"/>
<field name="contract_id" invisible="1"/>
</tree>
<form string="Create Employee Dependants">
<group>
<group>
<field name="name" required="1"/>
<field name="birthday" required="1"/>
<field name="relation" required="1"/>
<field name="passport_no"/>
<field name="passport_issue_date"/>
</group>
<group col="2">
<field name="age" required="1"/>
<field name="gender" required="1"/>
<field name="nationality" required="1"/>
<field name="identity_num" required="1"/>
<field name="passport_expire_date"/>
<!--field name="degree_medical_insu" />
<field name="medical_insurance_num" /-->
<field name="attachment" string="Attachment"
class="oe_inline"/>
<!-- <field name="attachment" string="Attachment"-->
<!-- widget="many2many_binary" class="oe_inline"/>-->
</group>
</group>
</form>
</field>
<separator string="Qualification"
attrs="{'invisible':[('request_type','!=','qualification')]}"/>
<field name="qualification_employee"
attrs="{'invisible':[('request_type','!=','qualification')],'readonly':[('state','!=','draft')]}">
<tree editable="bottom">
<field name="uni_name" required="1"/>
<field name="col_name" required="1"/>
<field name="qualification_id" string="Qualification Name" required="1"/>
<field name="qualification_specification_id" string="Qualification Specification"
required="1"/>
<field name="qualification_degree" string="Qualification Degree" required="1"/>
<field name="comp_date" required="1"/>
<!--field name="contact_name"/>
<field name="contact_phn" widget="phone"/>
<field name="contact_email" widget="email"/-->
<field name="country_name" string="Country"/>
<field name="attachment" string="Attachment" widget="binary"/>
</tree>
</field>
<separator string="Certification"
attrs="{'invisible':[('request_type','!=','certification')],'readonly':[('state','!=','draft')]}"/>
<field name="certification_employee"
attrs="{'invisible':[('request_type','!=','certification')],'readonly':[('state','!=','draft')]}">
<tree string='Certification' editable="bottom">
<field name="car_name"/>
<field name="certification_specification_id" string="Certification Specification"
required="1"/>
<field name="issue_org"/>
<field name="certification_degree" string="Certification Degree"/>
<field name="issue_date" required="1"/>
<field name="exp_date"/>
<field name="regis_no"/>
<!--field name="contact_name" />
<field name="contact_phn" widget="phone"/>
<field name="contact_email" widget="email"/-->
<field name="country_name" string="Country"/>
<field name="attachment" string="Attachment" widget="binary"/>
</tree>
</field>
</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"/>
</div>
</form>
</field>
</record>
<record id="employee_other_request_tree_view" model="ir.ui.view">
<field name="name">employee.other.request.tree.view</field>
<field name="model">employee.other.request</field>
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'" string="Employee Other Request">
<field name="employee_id" string="Employee Name"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job"/>
<field name="date" string="Date"/>
<field name="request_type" string="Request Type"/>
<field name="state" string="State"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
{
'name': 'HR Custody',
'category': 'Odex25-HR/Odex25-HR',
'summary': 'Custody and receiving Employee custody',
'version': '1.0',
'sequence': 4,
'website': 'http://exp-sa.com',
'license': 'GPL-3',
'author': 'Expert Co. Ltd.',
'depends': ['base','hr_base','employee_requests'],
'data': [
'security/ir.model.access.csv',
'security/custody_security.xml',
'views/employee_custody_views.xml',
'views/receiving_employee_custody.xml',
],
}

View File

@ -0,0 +1,753 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * exp_employee_custody
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-31 10:22+0000\n"
"PO-Revision-Date: 2023-01-31 10:22+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_needaction
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_needaction
msgid "Action Needed"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_ids
msgid "Activities"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_exception_decoration
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_state
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_state
msgid "Activity State"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_type_icon
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_type_icon
msgid "Activity Type Icon"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Add Comments here ...."
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__advantage_line_id
msgid "Advantage Line"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__amount
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Amount"
msgstr "المبلغ"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_attachment_count
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__call_compute_function
msgid "Call Compute Function"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__create_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__create_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__create_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__create_uid
msgid "Created by"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__create_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__create_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__create_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__create_date
msgid "Created on"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__current_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__current_date
msgid "Current Date"
msgstr ""
#. module: exp_employee_custody
#: model:ir.ui.menu,name:exp_employee_custody.custody_submenu
msgid "Custody"
msgstr "العُهــده"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__custody_line_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__custody_line_id
msgid "Custody Line"
msgstr "عهد الموظف"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Custody Lines"
msgstr "عهد الموظفين"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_tree_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_tree_view
msgid "Date"
msgstr "التاريخ"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Date Delivering"
msgstr "تاريخ الاستلام"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__deduction_amount
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__deduction_amount
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Deduction Amount"
msgstr "قيمة الخصم"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__department_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__department_id
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_tree_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_tree_view
msgid "Department"
msgstr "الإدارة"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Description"
msgstr "الوصف"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#, python-format
msgid "Direct Manager"
msgstr "المدير المباشر"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Directed Manager"
msgstr "المدير المباشر"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__display_name
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__display_name
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__display_name
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__display_name
msgid "Display Name"
msgstr ""
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#, python-format
msgid "Draft"
msgstr "مبدئي"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_tree_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_tree_view
msgid "Employee"
msgstr "الموظف"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#, python-format
msgid "Employee \"%s\" has not contract !"
msgstr "الموظف \"%s\" ليس لديه عقد!"
#. module: exp_employee_custody
#: model:ir.actions.act_window,name:exp_employee_custody.employee_custody_action
#: model:ir.ui.menu,name:exp_employee_custody.employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_tree_view
msgid "Employee Custody"
msgstr "العهد الغير مالية"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__employee_custody_line
msgid "Employee Custody Line"
msgstr "عهد الموظف"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__employee_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__employee_id
msgid "Employee"
msgstr "الموظف"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Employee Info"
msgstr "معلومات الموظف"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Employee Number"
msgstr "رقم الموظف"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__employee_return_custody_line_id
msgid "Employee Return Custody Line"
msgstr "عهد الموظف المرجعة"
#. module: exp_employee_custody
#: model:ir.model,name:exp_employee_custody.model_custom_employee_custody
msgid "Employee custody"
msgstr "العهد الغير مالية"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__employee_no
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__employee_no
msgid "Employee number"
msgstr "رقم الموظف"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_follower_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_follower_ids
msgid "Followers"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_channel_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_channel_ids
msgid "Followers (Channels)"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_partner_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__activity_type_icon
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__from_hr_department
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__from_hr_department
msgid "From Hr Department"
msgstr "من موظف آخر"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "HR Manager"
msgstr "مدير الموارد البشرية"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__admin
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__admin
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#, python-format
msgid "Human Resources Manager"
msgstr "تصديق الموارد البشرية"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__id
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__id
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__id
msgid "ID"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_exception_icon
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_exception_icon
msgid "Icon"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__activity_exception_icon
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Identification code"
msgstr "رقم المتسلسل"
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_needaction
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_unread
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_needaction
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_unread
msgid "If checked, new messages require your attention."
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_has_error
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_has_sms_error
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_has_error
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Invisible field to Call compute function"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_is_follower
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__job_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__job_id
msgid "Job Position"
msgstr "المناصب الوظيفية"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Job Title"
msgstr "الوظيفة"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody____last_update
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line____last_update
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line____last_update
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving____last_update
msgid "Last Modified on"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__write_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__write_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__write_uid
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__write_uid
msgid "Last Updated by"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__write_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__write_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__write_date
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__write_date
msgid "Last Updated on"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_main_attachment_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_main_attachment_id
msgid "Main Attachment"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_has_error
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_ids
msgid "Messages"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__my_activity_date_deadline
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__name
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__name
msgid "Name"
msgstr "الاسم"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Nationality"
msgstr "الجنسية"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__country_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__country_id
msgid "Nationality (Country)"
msgstr "الجنسية (البلد)"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_date_deadline
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_date_deadline
msgid "Next Activity Deadline"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_summary
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_summary
msgid "Next Activity Summary"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_type_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_type_id
msgid "Next Activity Type"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__note
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__note
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__note
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__note
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Note"
msgstr "ملاحظات"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Notes"
msgstr "ملاحظات"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_needaction_counter
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_has_error_counter
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_needaction_counter
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_has_error_counter
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__message_unread_counter
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__message_unread_counter
msgid "Number of unread messages"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Other Employee"
msgstr "موظف آخر"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__quantity
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__quantity
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Quantity"
msgstr "الكمية"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Re-fill"
msgstr "تحديث عهد الموظف"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__receiving_custody
msgid "Receiving Custody"
msgstr "تسوية العهده"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__receiving_date
msgid "Receiving Date"
msgstr "تاريخ الاستلام"
#. module: exp_employee_custody
#: model:ir.actions.act_window,name:exp_employee_custody.receiving_employee_custody_action
#: model:ir.ui.menu,name:exp_employee_custody.receiving_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_tree_view
msgid "Receiving Employee Custody"
msgstr "تسوية عهد الموظف"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Receiving Info"
msgstr "معلومات الارجاع"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__receiving_quantity
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Receiving Quantity"
msgstr "الكمية المرجعة"
#. module: exp_employee_custody
#: model:ir.model,name:exp_employee_custody.model_hr_custody_receiving
msgid "Receiving custody"
msgstr "تسوية العهده"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#, python-format
msgid "Receiving quantity can not be greater than original quantity"
msgstr "الكمية المرجعة لا يمكن أن تكون أكبر من الكمية المستلمة"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#, python-format
msgid "Receiving quantity can not be negative value "
msgstr "لا يمكن أن تكون كمية الاستلام قيمة سالبة"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
#, python-format
msgid "Refuse"
msgstr "رفض"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__activity_user_id
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__activity_user_id
msgid "Responsible User"
msgstr "المستخدم المسؤول"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "Rest To Draft"
msgstr "إرجاع لمبدئي"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__return_custody_line_ids
msgid "Return Custody Line"
msgstr "عهد الموظف المرجعة"
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__done
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__done
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
#, python-format
msgid "Return Done"
msgstr "تم ارجاع العهده"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Return Lines"
msgstr "عناصر العهد المرجعة"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_has_sms_error
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_has_sms_error
msgid "SMS Delivery error"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__salary_rule_id
msgid "Salary Rule"
msgstr "قاعده الراتب"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__salary_rule_flag
msgid "Salary Rule Flag"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Salary rule"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Salary rule flag"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Save contract advantage line"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_custody_line__serial
#: model:ir.model.fields,field_description:exp_employee_custody.field_employee_return_custody_line__serial
msgid "Serial"
msgstr "متسلسل"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Set to draft"
msgstr "إرجاع لمبدئي"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__state
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__state
msgid "State"
msgstr "الحالة"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Statement of Custody"
msgstr "العهد المرجعة"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_tree_view
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_tree_view
msgid "Status"
msgstr "الحالة"
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__activity_state
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Submit"
msgstr "إرسال"
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__activity_exception_decoration
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_unread
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_unread
msgid "Unread Messages"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__message_unread_counter
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__message_unread_counter
msgid "Unread Messages Counter"
msgstr ""
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__approve
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__approve
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
#, python-format
msgid "Warehouse Keeper"
msgstr "إعتماد مسؤول المخزن"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "Warehouse keeper"
msgstr "إعتماد مسؤول المخزن"
#. module: exp_employee_custody
#: model:ir.model.fields,field_description:exp_employee_custody.field_custom_employee_custody__website_message_ids
#: model:ir.model.fields,field_description:exp_employee_custody.field_hr_custody_receiving__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields,help:exp_employee_custody.field_custom_employee_custody__website_message_ids
#: model:ir.model.fields,help:exp_employee_custody.field_hr_custody_receiving__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#, python-format
msgid "You can not delete record in state not in draft"
msgstr "لا يمكن حذف السجل اذا كان في حالة غير مبدئي"
#. module: exp_employee_custody
#: model:ir.model,name:exp_employee_custody.model_employee_custody_line
msgid "employee.custody.line"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model,name:exp_employee_custody.model_employee_return_custody_line
msgid "employee.return.custody.line"
msgstr ""
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.receiving_employee_custody_form_view
msgid "line"
msgstr "بند"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "receiving_custody"
msgstr ""
#. module: exp_employee_custody
#: code:addons/exp_employee_custody/models/employee_custody.py:0
#: code:addons/exp_employee_custody/models/receiving_employee_custody.py:0
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__submit
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__submit
#, python-format
msgid "send"
msgstr "إرسال"
#. module: exp_employee_custody
#: model_terms:ir.ui.view,arch_db:exp_employee_custody.employee_custody_form_view
msgid "submit"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__direct
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__direct
msgid "المدير المباشر"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__refuse
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__refuse
msgid "رفض"
msgstr ""
#. module: exp_employee_custody
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__custom_employee_custody__state__draft
#: model:ir.model.fields.selection,name:exp_employee_custody.selection__hr_custody_receiving__state__draft
msgid "مسودة"
msgstr ""

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import employee_custody
from . import receiving_employee_custody

View File

@ -0,0 +1,90 @@
from odoo import models, fields, api, _, exceptions
from odoo import SUPERUSER_ID
# from datetime import datetime , date
class EmployeeCustody(models.Model):
_name = 'custom.employee.custody'
_rec_name = 'employee_id'
_description = 'Employee custody'
_inherit = ['mail.thread', 'mail.activity.mixin']
current_date = fields.Date(default=lambda self: fields.Date.today())
from_hr_department = fields.Boolean()
employee_no = fields.Char(related="employee_id.emp_no", readonly=True)
note = fields.Text()
state = fields.Selection(selection=[
("draft", _("Draft")),
("submit", _("send")),
("direct", _("Direct Manager")),
("admin", _("Human Resources Manager")),
("approve", _("Warehouse Keeper")),
("done", _("Return Done")),
("refuse", _("Refuse"))
], default='draft')
# Relational fields
receiving_custody = fields.Many2one('hr.custody.receiving')
custody_line_ids = fields.One2many('employee.custody.line', 'employee_custody_line')
employee_id = fields.Many2one('hr.employee', 'Employee', default=lambda item: item.get_user_id(),
domain=[('state', '=', 'open')])
department_id = fields.Many2one(related="employee_id.department_id", readonly=True)
job_id = fields.Many2one(related="employee_id.job_id", readonly=True)
country_id = fields.Many2one(related="employee_id.country_id", readonly=True)
def draft(self):
self.state = "draft"
def submit(self):
self.state = "submit"
def direct(self):
self.state = "direct"
def admin(self):
self.state = "admin"
def approve(self):
self.state = "approve"
def done(self):
self.state = "done"
def refuse(self):
self.state = "refuse"
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid), ('state', '=', 'open')], limit=1)
if employee_id:
return employee_id.id
else:
return False
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(EmployeeCustody, self).unlink()
EmployeeCustody()
class EmployeeCustodyLine(models.Model):
_name = 'employee.custody.line'
name = fields.Char()
serial = fields.Char()
quantity = fields.Float()
receiving_quantity = fields.Float()
note = fields.Char()
receiving_date = fields.Date()
amount = fields.Float()
# Relational fields
employee_custody_line = fields.Many2one(comodel_name='custom.employee.custody') # Inverse field
EmployeeCustodyLine()

View File

@ -0,0 +1,249 @@
from odoo import models, fields, api, _, exceptions
from odoo import SUPERUSER_ID
from datetime import datetime, date
import calendar
from pprint import pprint
class EmployeeReceiveCustody(models.Model):
_name = 'hr.custody.receiving'
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'employee_id'
_description = 'Receiving custody'
current_date = fields.Date(default=lambda self: fields.Date.today())
from_hr_department = fields.Boolean()
employee_no = fields.Char(related="employee_id.emp_no", readonly=True)
note = fields.Text()
deduction_amount = fields.Float()
salary_rule_flag = fields.Boolean()
state = fields.Selection(selection=[
("draft", _("Draft")),
("submit", _("send")),
("direct", _("Direct Manager")),
("admin", _("Human Resources Manager")),
("approve", _("Warehouse Keeper")),
("done", _("Return Done")),
("refuse", _("Refuse"))
], default='draft')
call_compute_function = fields.Char(compute='_get_custody_line_domain')
# Relational fields
department_id = fields.Many2one(related="employee_id.department_id", readonly=True)
job_id = fields.Many2one(related="employee_id.job_id", readonly=True)
country_id = fields.Many2one(related="employee_id.country_id", readonly=True)
return_custody_line_ids = fields.One2many('employee.return.custody.line', 'employee_return_custody_line_id',
store=True)
employee_id = fields.Many2one('hr.employee', 'Employee', default=lambda item: item.get_user_id())
salary_rule_id = fields.Many2one('hr.salary.rule', domain=['|', ('category_id.rule_type', '=', 'deduction'),
('category_id.name', '=', 'Deduction')])
advantage_line_id = fields.Many2one('contract.advantage') # To save advantage line
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
@api.depends('employee_id')
def _get_custody_line_domain(self):
for item in self:
item.return_custody_line_ids = [(0, 0, val) for val in []]
if item.employee_id:
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', item.employee_id.id), ('state', 'in', ['approve', 'done'])])
items = []
for record in employee_custody:
if ((item.state == 'done' and record.state == 'done') and (
record.receiving_custody.id == item.id)) or record.state == 'approve':
for line in record.custody_line_ids:
if line.quantity - line.receiving_quantity > 0 and line.amount == 0:
items.append({
'name': line.name,
'serial': line.serial,
'employee_return_custody_line_id': item.id,
'quantity': line.quantity - line.receiving_quantity,
'note': line.note,
'custody_line_id': line.id})
item.return_custody_line_ids = [(0, 0, val) for val in items]
# Re-fill receive custody lines
def re_fill_receive_custody_lines(self):
for item in self:
item.return_custody_line_ids = False
if item.employee_id:
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', item.employee_id.id), ('state', 'in', ['approve', 'done'])])
items = []
for record in employee_custody:
if ((item.state == 'done' and record.state == 'done') and (
record.receiving_custody.id == item.id)) or record.state == 'approve':
for line in record.custody_line_ids:
if line.quantity - line.receiving_quantity > 0 and line.amount == 0:
items.append({
'name': line.name,
'serial': line.serial,
'employee_return_custody_line_id': item.id,
'quantity': line.quantity - line.receiving_quantity,
'note': line.note,
'custody_line_id': line.id})
item.return_custody_line_ids = [(0, 0, val) for val in items]
@api.onchange('return_custody_line_ids')
def compute_deduction_amount(self):
total_amount = 0.0
for item in self:
item.salary_rule_flag = False
for line in item.return_custody_line_ids:
total_amount += line.deduction_amount
item.deduction_amount = total_amount
# salary_rule_flag Flag do visible salary rule
if item.deduction_amount > 0.0:
item.salary_rule_flag = True
def set_to_draft(self):
for item in self:
if item.employee_id and item.state == 'done':
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', item.employee_id.id), ('state', 'in', ['done', 'approve'])])
for line in employee_custody:
for element in self.return_custody_line_ids:
for custody in line.custody_line_ids:
if custody.receiving_quantity > 0.0:
line.state = 'approve'
if element.custody_line_id.id == custody.id:
if custody.receiving_quantity - element.quantity >= 0:
custody.receiving_quantity = custody.receiving_quantity - element.quantity
custody.amount = 0.0
else:
raise exceptions.Warning(_('Receiving quantity can not be negative value '))
# Remove contract advantage line when re-draft
if item.advantage_line_id:
item.advantage_line_id.unlink()
self.state = 'draft'
def send(self):
self.state = 'submit'
def dr_manager(self):
self.state = 'direct'
def dr_hr_manager(self):
self.state = 'admin'
def done(self):
for item in self:
# If return any custody quantity fill it in receiving quantity
for line in item.return_custody_line_ids:
if (line.custody_line_id.receiving_quantity + line.quantity) > line.custody_line_id.quantity:
raise exceptions.Warning(_('Receiving quantity can not be greater than original quantity'))
else:
line.custody_line_id.receiving_quantity = line.custody_line_id.receiving_quantity + line.quantity
line.custody_line_id.amount = line.deduction_amount
if line.custody_line_id.receiving_quantity < 0.0:
raise exceptions.Warning(_('Receiving quantity can not be negative value '))
if item.employee_id:
custody_not_complete = 0.0
employee_custody = self.env['custom.employee.custody'].search(
[('employee_id', '=', item.employee_id.id), ('state', '=', 'approve')])
for record in employee_custody:
record.write({
'receiving_custody': item.id,
})
# Check all employee custody line are completed the change state to done
for record in employee_custody:
for line in record.custody_line_ids:
if line.receiving_quantity != line.quantity and line.amount == 0.0:
custody_not_complete += 1
if custody_not_complete == 0:
record.state = 'done'
# Move deduction amount to employee contract advantage lines
if item.employee_id.contract_id:
if item.deduction_amount and item.salary_rule_id:
contract = item.employee_id.contract_id
# get start and end date of the current month
current_date = date.today()
month_start = date(current_date.year, current_date.month, 1)
month_end = date(current_date.year, current_date.month, calendar.mdays[current_date.month])
advantage_line_id = self.env['contract.advantage'].create({
'benefits_discounts': item.salary_rule_id.id,
'type': 'customize',
'date_from': month_start,
'date_to': month_end,
'amount': item.deduction_amount,
'contract_advantage_id': contract.id,
})
item.advantage_line_id = advantage_line_id.id
else:
raise exceptions.Warning(_('Employee "%s" has not contract !') % item.employee_id.name)
item.state = 'done'
def warehouse_keeper(self):
self.state = 'approve'
def refuse(self):
self.state = 'refuse'
# Override create function
# make sure the one2many return_custody_line_ids save changes when create and updates
# @api.model
# def create(self , values):
# deduction_amount = values.get('return_custody_line_ids')
# deduction_amount_list = []
# quantity_list = []
#
# for line in deduction_amount:
# deduction_amount_list.append(line[2]['deduction_amount'])
# quantity_list.append(line[2]['quantity'])
# print(deduction_amount)
# print(deduction_amount_list)
# res = super(EmployeeReceiveCustody ,self).create(values)
#
# index = 0
# for element in res.return_custody_line_ids:
# element.deduction_amount = deduction_amount_list[index]
# element.quantity = quantity_list[index]
# index +=1
#
# print(quantity_list)
# return res
# Override unlink function
def unlink(self):
for i in self:
if i.state != 'draft':
raise exceptions.Warning(_('You can not delete record in state not in draft'))
return super(EmployeeReceiveCustody, self).unlink()
class EmployeeReturnCustodyLine(models.Model):
_name = 'employee.return.custody.line'
_rec_name = 'name'
name = fields.Char()
serial = fields.Char()
quantity = fields.Float()
note = fields.Char()
deduction_amount = fields.Float()
# Relational fields
employee_return_custody_line_id = fields.Many2one(comodel_name='hr.custody.receiving') # inverse field
custody_line_id = fields.Many2one('employee.custody.line') # to save custody_id

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="custom_employee_custody_emp_rule" model="ir.rule">
<field name="name">Employee: views custody</field>
<field name="model_id" ref="model_custom_employee_custody"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="custom_employee_custody_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views custody of its subordinates</field>
<field name="model_id" ref="model_custom_employee_custody"/>
<field name="domain_force">['|',('employee_id.parent_id.user_id','=', user.id),('employee_id.coach_id.user_id','=', user.id)]</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="custom_employee_custody_hr_rule" model="ir.rule">
<field name="name">Allow HR : views custody of all employees</field>
<field name="model_id" ref="model_custom_employee_custody"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="hr_custody_receiving_emp_rule" model="ir.rule">
<field name="name">Employee: views its custody receiving records</field>
<field name="model_id" ref="model_hr_custody_receiving"/>
<field name="domain_force">[('employee_id.user_id','=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="hr_custody_receiving_division_mgr_rule" model="ir.rule">
<field name="name">Division manager: views custody receiving records of its subordinates</field>
<field name="model_id" ref="model_hr_custody_receiving"/>
<field name="domain_force">['|',('employee_id.parent_id.user_id','=', user.id),('employee_id.coach_id.user_id','=', user.id)]</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager')),]"/>
</record>
<record id="hr_custody_receiving_hr_rule" model="ir.rule">
<field name="name">Allow HR : views custody receiving records of all employees</field>
<field name="model_id" ref="model_hr_custody_receiving"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('hr.group_hr_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
</data>
</odoo>

View File

@ -0,0 +1,6 @@
id,name,model_id:id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_hr_custody_receiving,access_hr_custody_receiving,exp_employee_custody.model_hr_custody_receiving,base.group_user,1,0,0,0
access_hr_custody_receiving_emp,hr.custody.receiving.emp,exp_employee_custody.model_hr_custody_receiving,base.group_user,1,1,1,1
access_employee_custody,access_employee_custody,exp_employee_custody.model_custom_employee_custody,base.group_user,1,1,1,1
access_employee_custody_line,access_employee_custody_line,exp_employee_custody.model_employee_custody_line,base.group_user,1,1,1,1
access_employee_return_custody_emp,Employee.return.custody.line.emp,exp_employee_custody.model_employee_return_custody_line,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_custody_receiving access_hr_custody_receiving exp_employee_custody.model_hr_custody_receiving base.group_user 1 0 0 0
3 access_hr_custody_receiving_emp hr.custody.receiving.emp exp_employee_custody.model_hr_custody_receiving base.group_user 1 1 1 1
4 access_employee_custody access_employee_custody exp_employee_custody.model_custom_employee_custody base.group_user 1 1 1 1
5 access_employee_custody_line access_employee_custody_line exp_employee_custody.model_employee_custody_line base.group_user 1 1 1 1
6 access_employee_return_custody_emp Employee.return.custody.line.emp exp_employee_custody.model_employee_return_custody_line base.group_user 1 1 1 1

Some files were not shown because too many files have changed in this diff Show More