Add odex25_hr
This commit is contained in:
parent
3a3f834c54
commit
0be409eab9
|
|
@ -1,2 +1,2 @@
|
||||||
# odex25-standard-moduless
|
# odex25-standard-modules
|
||||||
This Repo contains general standard modules for all projects.
|
This Repo contains general standard modules for all projects.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import models
|
||||||
|
|
@ -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,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import hr_employee
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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;
|
||||||
|
});
|
||||||
|
|
@ -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;
|
||||||
|
});
|
||||||
|
|
@ -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&field=image_128&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&field=image_128&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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
from . import report
|
||||||
|
|
@ -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,
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
@ -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
|
||||||
|
|
@ -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'
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
|
@ -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"
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 &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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from . import attendance_wizard
|
||||||
|
from . import attendances_report_wiz
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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:
|
||||||
|
|
@ -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:
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# LCT, Life Connection Technology
|
||||||
|
# Copyright (C) 2011-2012 LCT
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
from . import res_users
|
||||||
|
|
@ -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 |
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
from . import report
|
||||||
|
|
@ -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
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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')
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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')
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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')
|
||||||
|
|
@ -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')
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import report_employee_identification
|
||||||
|
from . import report_employee_identification1
|
||||||
|
from . import report_employee_identification2
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
|
@ -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',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -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 ""
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import employee_custody
|
||||||
|
from . import receiving_employee_custody
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue