[IMP] hr_attendance
- remove wizards 'hr.sign.in.out.ask' and 'hr.sign.in.out' for simply Attendance action. - code clean of 'attendance_action_change' of hr.employee. - code clean of AttendanceNotifier widget and also overrides methods of DataSet widget to update AttendanceNotifier widget base on employee attendance. bzr revid: hmo@tinyerp.com-20120511054711-uah7h2af9bbx7nch
|
@ -44,7 +44,6 @@ actions(Sign in/Sign out) performed by them.
|
|||
'wizard/hr_attendance_bymonth_view.xml',
|
||||
'wizard/hr_attendance_byweek_view.xml',
|
||||
'wizard/hr_attendance_error_view.xml',
|
||||
'wizard/hr_attendance_sign_in_out_view.xml',
|
||||
],
|
||||
'demo_xml': ['hr_attendance_demo.xml'],
|
||||
'test': [
|
||||
|
@ -57,7 +56,6 @@ actions(Sign in/Sign out) performed by them.
|
|||
|
||||
#web
|
||||
"js": ["static/src/js/attendance.js"],
|
||||
"css":["static/src/css/attendance.css"],
|
||||
'qweb' : ["static/src/xml/attendance.xml"],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -122,30 +122,25 @@ class hr_employee(osv.osv):
|
|||
res = cr.fetchone()
|
||||
return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))
|
||||
|
||||
def attendance_action_change(self, cr, uid, ids, type='action', context=None, dt=False, *args):
|
||||
obj_attendance = self.pool.get('hr.attendance')
|
||||
id = False
|
||||
warning_sign = 'sign'
|
||||
res = {}
|
||||
def attendance_action_change(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
action_date = context.get('action_date', False)
|
||||
action = context.get('action', False)
|
||||
hr_attendance = self.pool.get('hr.attendance')
|
||||
warning_sign = {'sign_in': _('Sign In'), 'sign_out': _('Sign Out')}
|
||||
for employee in self.browse(cr, uid, ids, context=context):
|
||||
if not action:
|
||||
if employee.state == 'present': action = 'sign_out'
|
||||
if employee.state == 'absent': action = 'sign_in'
|
||||
|
||||
#Special case when button calls this method: type=context
|
||||
if isinstance(type, dict):
|
||||
type = type.get('type','action')
|
||||
if type == 'sign_in':
|
||||
warning_sign = "Sign In"
|
||||
elif type == 'sign_out':
|
||||
warning_sign = "Sign Out"
|
||||
for emp in self.read(cr, uid, ids, ['id'], context=context):
|
||||
if not self._action_check(cr, uid, emp['id'], dt, context):
|
||||
raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))
|
||||
if not self._action_check(cr, uid, employee.id, action_date, context):
|
||||
raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the HR Manager to correct attendances.')%(warning_sign[action],))
|
||||
|
||||
res = {'action': type, 'employee_id': emp['id']}
|
||||
if dt:
|
||||
res['name'] = dt
|
||||
id = obj_attendance.create(cr, uid, res, context=context)
|
||||
|
||||
if type != 'action':
|
||||
return id
|
||||
vals = {'action': action, 'employee_id': employee.id}
|
||||
if action_date:
|
||||
vals['name'] = action_date
|
||||
hr_attendance.create(cr, uid, vals, context=context)
|
||||
return True
|
||||
|
||||
hr_employee()
|
||||
|
|
|
@ -130,8 +130,8 @@
|
|||
<field name="coach_id" position="after">
|
||||
<group colspan="2">
|
||||
<field name="state"/>
|
||||
<button name="%(action_hr_attendance_sigh_in_out)d" states="present" type="action" string="Sign Out" icon="gtk-go-forward" context="{'type':'sign_out'}" groups="base.group_hr_user"/>
|
||||
<button name="%(action_hr_attendance_sigh_in_out)d" states="absent" type="action" string="Sign In" icon="gtk-go-back" context="{'type':'sign_in'}" groups="base.group_hr_user"/>
|
||||
<button name="attendance_action_change" states="present" type="object" string="Sign Out" icon="gtk-go-forward" groups="base.group_hr_manager"/>
|
||||
<button name="attendance_action_change" states="absent" type="object" string="Sign In" icon="gtk-go-back" groups="base.group_hr_manager"/>
|
||||
</group>
|
||||
</field>
|
||||
</field>
|
||||
|
@ -139,3 +139,5 @@
|
|||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
.oe_attendance_button {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 5.8 KiB |
|
@ -1,71 +1,87 @@
|
|||
openerp.hr_attendance = function(instance) {
|
||||
var QWeb = instance.web.qweb;
|
||||
instance.hr_attendance.attendancestatus = false,
|
||||
instance.hr_attendance.checkstatus = function(){
|
||||
attendance = instance.hr_attendance.currentstatus;
|
||||
if (!attendance){
|
||||
attendance = new instance.hr_attendance.AttendanceNotifier(self);
|
||||
instance.hr_attendance.currentstatus = attendance;
|
||||
}
|
||||
attendance.renderElement();
|
||||
},
|
||||
instance.hr_attendance.callback = function(callback){
|
||||
var old_callback = callback;
|
||||
callback = function(result){
|
||||
if(old_callback){old_callback(result);}
|
||||
instance.hr_attendance.checkstatus();
|
||||
}
|
||||
return callback;
|
||||
},
|
||||
instance.hr_attendance.AttendanceNotifier = instance.web.Widget.extend({
|
||||
template: 'AttendanceNotifier',
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
if (this.attendance_status == 'present'){
|
||||
action_type = 'sign_out';
|
||||
}
|
||||
else{
|
||||
action_type = 'sign_in';
|
||||
}
|
||||
this.$element = $(QWeb.render(this.template, {'action':action_type}));
|
||||
employee = new instance.web.DataSetSearch(this, 'hr.employee', this.session.user_context, [['user_id','=', this.session.uid]]);
|
||||
employee.read_slice(['id','name','state']).done(function(employee) {
|
||||
if(_.isEmpty(employee)) return;
|
||||
self.employee = employee[0];
|
||||
self.do_update_notifier();
|
||||
});
|
||||
},
|
||||
do_update_notifier: function(){
|
||||
var self = this;
|
||||
this.$element = $(QWeb.render(this.template, {'employee':this.employee}));
|
||||
this.$element.click(self.on_click);
|
||||
element = $('.oe_attendance_button')
|
||||
if (element.length != 0){
|
||||
element.attr('src', this.$element.attr('src'));
|
||||
element.replaceWith(this.$element);
|
||||
}
|
||||
else{
|
||||
this.$element.appendTo($('.oe_systray'));
|
||||
this.$element.click(self.on_click);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
on_click: function() {
|
||||
var self = this;
|
||||
action = new instance.web.DataSetSearch(this, 'ir.actions.act_window', {}, [['res_model', '=', 'hr.sign.in.out']]);
|
||||
action.read_slice().done(function(action) {
|
||||
action = action[0];
|
||||
action.context = JSON.parse(action.context);
|
||||
var action_manager = new instance.web.ActionManager(self);
|
||||
action_manager.do_action(action);
|
||||
});
|
||||
hr_employee = new instance.web.DataSet(self, 'hr.employee');
|
||||
hr_employee.call('attendance_action_change', [[self.employee.id]]).done(function(result){self.renderElement()});
|
||||
},
|
||||
});
|
||||
|
||||
instance.hr_attendance.AttendanceStatus = instance.web.Class.extend({
|
||||
init: function(parent){
|
||||
this.session = parent.session;
|
||||
attendance = new instance.hr_attendance.AttendanceNotifier(self);
|
||||
employee = new instance.web.DataSetSearch(this, 'hr.employee', this.session.user_context, [['user_id','=', this.session.uid]]);
|
||||
employee.read_slice(['state']).done(function(employee) {
|
||||
if(_.isEmpty(employee)) return;
|
||||
attendance.attendance_status = employee[0]['state'];
|
||||
attendance.renderElement();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
instance.web.ActionManager.include({
|
||||
do_action: function(action, on_close) {
|
||||
var self = this;
|
||||
if (action.res_model == "hr.sign.in.out"){
|
||||
var old_close = on_close;
|
||||
on_close = function(){
|
||||
if(old_close){old_close();}
|
||||
new instance.hr_attendance.AttendanceStatus(self);
|
||||
}
|
||||
instance.web.DataSet.include({
|
||||
create: function(data, callback, error_callback) {
|
||||
if (this._model.name == "hr.attendance"){
|
||||
callback = instance.hr_attendance.callback(callback);
|
||||
}
|
||||
this._super(action, on_close);
|
||||
},
|
||||
return this._super(data, callback, error_callback);
|
||||
},
|
||||
write: function (id, data, options, callback, error_callback) {
|
||||
if (this._model.name == "hr.attendance"){
|
||||
callback = instance.hr_attendance.callback(callback);
|
||||
}
|
||||
return this._super(id, data, options, callback, error_callback);
|
||||
},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
if (this._model.name == "hr.attendance"){
|
||||
callback = instance.hr_attendance.callback(callback);
|
||||
}
|
||||
return this._super(ids, callback, error_callback);
|
||||
},
|
||||
call_button: function (method, args, callback, error_callback) {
|
||||
if (this._model.name == "hr.employee" && method == "attendance_action_change"){
|
||||
callback = instance.hr_attendance.callback(callback);
|
||||
}
|
||||
return this._super(method, args, callback, error_callback);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
instance.web.UserMenu.include({
|
||||
do_update: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
this.update_promise.then(function() {
|
||||
new instance.hr_attendance.AttendanceStatus(self);
|
||||
instance.hr_attendance.checkstatus();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
<template>
|
||||
<t t-name="AttendanceNotifier">
|
||||
<t t-if="action=='sign_in'">
|
||||
<img src="/hr_attendance/static/src/img/emp-in.png" class="oe_attendance_button"></img>
|
||||
</t>
|
||||
<t t-if="action=='sign_out'">
|
||||
<img src="/hr_attendance/static/src/img/emp-out.png" class="oe_attendance_button"></img>
|
||||
</t>
|
||||
|
||||
<a href="#" class="oe_attendance_button" t-attf-title="You are #{employee.state}">
|
||||
<img t-attf-src="/hr_attendance/static/src/img/emp-#{employee.state}.png" ></img>
|
||||
</a>
|
||||
</t>
|
||||
</template>
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import hr_attendance_sign_in_out
|
||||
import hr_attendance_error
|
||||
import hr_attendance_byweek
|
||||
import hr_attendance_bymonth
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import time
|
||||
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
|
||||
class hr_si_so_ask(osv.osv_memory):
|
||||
_name = 'hr.sign.in.out.ask'
|
||||
_description = 'Ask for Sign In Out'
|
||||
_columns = {
|
||||
'name': fields.char('Employees name', size=32, required=True, readonly=True),
|
||||
'last_time': fields.datetime('Your last sign out', required=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Empoyee ID', readonly=True),
|
||||
}
|
||||
|
||||
def _get_empname(self, cr, uid, context=None):
|
||||
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
|
||||
if emp_id:
|
||||
employee = self.pool.get('hr.employee').browse(cr, uid, emp_id, context=context)[0].name
|
||||
return employee
|
||||
return ''
|
||||
|
||||
def _get_empid(self, cr, uid, context=None):
|
||||
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
|
||||
if emp_id:
|
||||
return emp_id[0]
|
||||
return False
|
||||
|
||||
_defaults = {
|
||||
'name': _get_empname,
|
||||
'emp_id': _get_empid,
|
||||
}
|
||||
|
||||
def sign_in(self, cr, uid, ids, context=None):
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
|
||||
return self.pool.get('hr.sign.in.out').sign_in(cr, uid, data, context)
|
||||
|
||||
def sign_out(self, cr, uid, ids, context=None):
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
|
||||
return self.pool.get('hr.sign.in.out').sign_out(cr, uid, data, context)
|
||||
|
||||
hr_si_so_ask()
|
||||
|
||||
class hr_sign_in_out(osv.osv_memory):
|
||||
_name = 'hr.sign.in.out'
|
||||
_description = 'Sign In Sign Out'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Employees name', size=32, required=True, readonly=True),
|
||||
'state': fields.char('Current state', size=32, required=True, readonly=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Empoyee ID', readonly=True),
|
||||
}
|
||||
|
||||
def _get_empid(self, cr, uid, context=None):
|
||||
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
|
||||
if emp_id:
|
||||
employee = self.pool.get('hr.employee').browse(cr, uid, emp_id, context=context)[0]
|
||||
return {'name': employee.name, 'state': employee.state, 'emp_id': emp_id[0]}
|
||||
return {}
|
||||
|
||||
def default_get(self, cr, uid, fields_list, context=None):
|
||||
res = super(hr_sign_in_out, self).default_get(cr, uid, fields_list, context=context)
|
||||
res_emp = self._get_empid(cr, uid, context=context)
|
||||
act_obj=self.pool.get('ir.actions.act_window')
|
||||
action_id = act_obj.search(cr, uid, [('res_model','=','hr.sign.in.out')],context=context)
|
||||
action = act_obj.browse(cr, uid, action_id[0], context=context)
|
||||
if res_emp['state']=='present':
|
||||
name = act_obj.write(cr, uid, action_id[0], {'name':'Sign Out'}, context=context)
|
||||
if res_emp['state']=='absent':
|
||||
name = act_obj.write(cr, uid, action_id[0], {'name':'Sign In'}, context=context)
|
||||
res.update(res_emp)
|
||||
return res
|
||||
|
||||
def si_check(self, cr, uid, ids, context=None):
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
att_obj = self.pool.get('hr.attendance')
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
|
||||
emp_id = data['emp_id']
|
||||
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id)], limit=1, order='name desc')
|
||||
last_att = att_obj.browse(cr, uid, att_id, context=context)
|
||||
if last_att:
|
||||
last_att = last_att[0]
|
||||
cond = not last_att or last_att.action == 'sign_out'
|
||||
if cond:
|
||||
return self.sign_in(cr, uid, data, context)
|
||||
else:
|
||||
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_hr_attendance_so_ask')], context=context)
|
||||
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
|
||||
return {
|
||||
'name': _('Sign in '),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'hr.sign.in.out.ask',
|
||||
'views': [(resource_id,'form')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'context': context,
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def so_check(self, cr, uid, ids, context=None):
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
att_obj = self.pool.get('hr.attendance')
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
|
||||
emp_id = data['emp_id']
|
||||
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id),('action', '!=', 'action')], limit=1, order='name desc')
|
||||
last_att = att_obj.browse(cr, uid, att_id, context=context)
|
||||
if last_att:
|
||||
last_att = last_att[0]
|
||||
if not att_id and not last_att:
|
||||
model_data_ids = obj_model.search(cr, uid, [('model','=','ir.ui.view'),('name','=','view_hr_attendance_message')], context=context)
|
||||
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
|
||||
return {
|
||||
'name': _('Sign in / Sign out'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'hr.sign.in.out',
|
||||
'views': [(resource_id,'form')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'context': context,
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
cond = last_att and last_att['action'] == 'sign_in'
|
||||
if cond:
|
||||
return self.sign_out(cr, uid, data, context)
|
||||
else:
|
||||
model_data_ids = obj_model.search(cr, uid, [('model','=','ir.ui.view'),('name','=','view_hr_attendance_si_ask')], context=context)
|
||||
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
|
||||
return {
|
||||
'name': _('Sign in / Sign out'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'hr.sign.in.out.ask',
|
||||
'views': [(resource_id,'form')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def sign_in(self, cr, uid, data, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
emp_id = data['emp_id']
|
||||
if 'last_time' in data:
|
||||
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
|
||||
raise osv.except_osv(_('UserError'), _('The sign-out date must be in the past'))
|
||||
self.pool.get('hr.attendance').create(cr, uid, {'name': data['last_time'], 'action': 'sign_out',
|
||||
'employee_id': emp_id}, context=context)
|
||||
try:
|
||||
self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_in')
|
||||
except:
|
||||
raise osv.except_osv(_('UserError'), _('A sign-in must be right after a sign-out !'))
|
||||
return {'type': 'ir.actions.act_window_close'} # To do: Return Success message
|
||||
|
||||
def sign_out(self, cr, uid, data, context=None):
|
||||
emp_id = data['emp_id']
|
||||
if 'last_time' in data:
|
||||
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
|
||||
raise osv.except_osv(_('UserError'), _('The Sign-in date must be in the past'))
|
||||
self.pool.get('hr.attendance').create(cr, uid, {'name':data['last_time'], 'action':'sign_in', 'employee_id':emp_id}, context=context)
|
||||
try:
|
||||
self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_out')
|
||||
except:
|
||||
raise osv.except_osv(_('UserError'), _('A sign-out must be right after a sign-in !'))
|
||||
return {'type': 'ir.actions.act_window_close'} # To do: Return Success message
|
||||
|
||||
hr_sign_in_out()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,92 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_hr_attendance_sigh_in_out" model="ir.ui.view">
|
||||
<field name="name">hr.sign.in.out.form</field>
|
||||
<field name="model">hr.sign.in.out</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sign in / Sign out">
|
||||
<label colspan="4" nolabel="1" string="If you need your staff to sign in when they arrive at work and sign out again at the end of the day, OpenERP allows you to manage this with this tool. If each employee has been linked to a system user, then they can encode their time with this action button."/>
|
||||
<newline/>
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" />
|
||||
<field name="state" />
|
||||
</group>
|
||||
<separator colspan="4"/>
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||
<button icon="terp-gtk-jump-to-ltr" string="Sign in" name="si_check" type="object" attrs="{'invisible':[('state','=','present')]}"/>
|
||||
<button icon="terp-gtk-jump-to-rtl" string="Sign out" name="so_check" type="object" attrs="{'invisible':[('state','=','absent')]}"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_attendance_message" model="ir.ui.view">
|
||||
<field name="name">hr.sign.in.out.form</field>
|
||||
<field name="model">hr.sign.in.out</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sign in / Sign out">
|
||||
<separator string="Sign-Out Entry must follow Sign-In." colspan="4" />
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="Ok"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_attendance_sigh_in_out" model="ir.actions.act_window">
|
||||
<field name="name">Sign In / Sign Out</field>
|
||||
<field name="res_model">hr.sign.in.out</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_hr_attendance_sigh_in_out"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Sign in / Sign out. In some companies, staff have to sign in when they arrive at work and sign out again at the end of the day. If each employee has been linked to a system user, then they can encode their time with this action button.</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_hr_attendance_so_ask" model="ir.ui.view">
|
||||
<field name="name">hr.sign.in.out.ask.form</field>
|
||||
<field name="model">hr.sign.in.out.ask</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="hr.sign.out.ask">
|
||||
<group colspan="4" >
|
||||
<separator string="You did not sign out the last time. Please enter the date and time you signed out." colspan="4" />
|
||||
<field name="name" />
|
||||
<field name="last_time" string="Your last sign out" />
|
||||
</group>
|
||||
<separator colspan="4" />
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||
<button icon="gtk-go-back" string="Sign in" name="sign_in" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_attendance_si_ask" model="ir.ui.view">
|
||||
<field name="name">hr.sign.in.out.ask.form</field>
|
||||
<field name="model">hr.sign.in.out.ask</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="hr.sign.in.out.ask">
|
||||
<group colspan="4" >
|
||||
<separator string="You did not sign in the last time. Please enter the date and time you signed in." colspan="4" />
|
||||
<field name="name" />
|
||||
<field name="last_time" string="Your last sign in" />
|
||||
</group>
|
||||
<separator colspan="4" />
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||
<button icon="gtk-go-back" string="Sign out" name="sign_out" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -91,8 +91,6 @@
|
|||
</field>
|
||||
<group col="4" colspan="1">
|
||||
<field name="state_attendance"/>
|
||||
<button name="%(hr_attendance.action_hr_attendance_sigh_in_out)d" type="action" string="Sign In" attrs="{'invisible':[('state_attendance','=','present')]}" icon="terp-gtk-jump-to-ltr" />
|
||||
<button name="%(hr_attendance.action_hr_attendance_sigh_in_out)d" type="action" string="Sign Out" attrs="{'invisible':[('state_attendance','=','absent')]}" icon="terp-gtk-jump-to-rtl" />
|
||||
<field name="total_attendance_day" widget="float_time" colspan="4"/>
|
||||
</group>
|
||||
<field colspan="4" context="{'date':date_current,'user_id':user_id}" domain="[('name','=',date_current)]" name="timesheet_ids" nolabel="1">
|
||||
|
|