############################################################################## # # Copyright (c) 2005 TINY SPRL. (http://tiny.be) All Rights Reserved. # # $Id: hr.py 2189 2006-01-22 19:26:30Z pinky $ # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential # consequences resulting from its eventual inadequacies and bugs # End users who are looking for a ready-to-use solution with commercial # garantees and support are strongly adviced to contract a Free Software # Service Company # # This program is Free Software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## from mx import DateTime import time import netsvc from osv import fields, osv, orm class hr_timesheet_group(osv.osv): _name = "hr.timesheet.group" _description = "Timesheet" _columns = { 'name' : fields.char("Group name", size=128), 'timesheet_id' : fields.one2many('hr.timesheet', 'tgroup_id', 'Timesheet'), 'manager' : fields.many2one('res.users', 'Workgroup manager'), } # # TODO: imrpove; very slow ! # bug if transition to another period # def interval_get(self, cr, uid, id, dt_from, hours, byday=True): if not id: return [(dt_from,dt_from+DateTime.RelativeDateTime(hours=int(hours)*3))] todo = hours cycle = 0 result = [] while todo>0: cr.execute('select hour_from,hour_to from hr_timesheet where dayofweek=%d and tgroup_id=%d order by hour_from', (dt_from.day_of_week,id)) for (hour_from,hour_to) in cr.fetchall(): h1,m1 = map(int,hour_from.split(':')) h2,m2 = map(int,hour_to.split(':')) d1 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,h1,m1) d2 = DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,h2,m2) if dt_from7 and todo==hours: return [(dt_from,dt_from+DateTime.RelativeDateTime(hours=hours*3))] if byday: i = 1 while i= 16: yesterday = (now().day_of_week + 6) % 7 cr.execute("select hour_to from hr_timesheet as ts, hr_timesheet_group as tsg, hr_employee as emp, hr_timesheet_employee_rel as rel where ts.dayofweek<=%d and ts.tgroup_id= tsg.id and emp.id=%d and tsg.id=rel.tgroup_id and emp.id=rel.emp_id order by ts.dayofweek desc, ts.date_from desc,ts.hour_to desc limit 1", (yesterday, emp.id)) last = cr.dictfetchall() if last: self.pool.get('hr.attendance').write(cr, uid, [att_id], {'name' : last[0]['hour_to']}) if emp.workgroups and emp.workgroups[0].manager: request = self.pool.get('res.request') request.create(cr, uid, {'name' : "%s's sign out time" % emp.name, 'req_ref' : 'hr:employee:%d' % emp.id, 'req_type' : 'info', 'req_priority' : str(0), 'state' : 'wait', 'req_summary' : "Too long sign out delay (%f hours) for %s" % (elapsed_time.hours, emp.name), 'act_from' : emp.id, 'act_to' : emp.workgroups[0].manager.id, 'act_title' : "Too long sign out delay", }) return True def sign_in(self, cr, uid, ids, *args): for emp in self.browse(cr, uid, ids): self.pool.get('hr.attendance').create(cr, uid, {'action':'sign_in', 'employee_id':emp.id}) self.write(cr, uid, [emp.id], {'state':'present'}) return True hr_employee() class hr_timesheet(osv.osv): _name = "hr.timesheet" _description = "Timesheet Line" _columns = { 'name' : fields.char("Name", size=128), 'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of week'), 'date_from' : fields.date('Starting date'), 'hour_from' : fields.char('Work from', size=8), 'hour_to' : fields.char("Work to", size=8), 'tgroup_id' : fields.many2one("hr.timesheet.group", "Employee's timesheet group"), } _order = 'hour_from desc,dayofweek desc' hr_timesheet() class hr_action_reason(osv.osv): _name = "hr.action.reason" _description = "Action reason" _columns = { 'name' : fields.char('Reason', size=64), 'action_type' : fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action's type"), } hr_action_reason() def _employee_get(obj,cr,uid,context={}): ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)]) if ids: return ids[0] return False class hr_attendance(osv.osv): _name = "hr.attendance" _description = "Attendance" _columns = { 'name' : fields.datetime('Date', size=16), 'action' : fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out')], 'Action'), 'action_desc' : fields.many2one("hr.action.reason", "Action reason", domain="[('action_type', '=', action)]"), 'employee_id' : fields.many2one('hr.employee', 'Employee',required=True), } _defaults = { 'name' : lambda *a: time.strftime('%Y-%m-%d %H:%M'), 'employee_id' : _employee_get, } def _altern_si_so(self, cr, uid, ids): sql = ''' select action, name from hr_attendance as att where employee_id = (select employee_id from hr_attendance where id=%s) order by id desc limit 2 ''' % ids[0] cr.execute(sql) atts = cr.fetchall() return (len(atts)==1 and atts[0][0] == 'sign_in') or (atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1]) _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])] _order = 'name desc' hr_attendance() class hr_holidays_status(osv.osv): _name = "hr.holidays.status" _description = "Holidays Status" _columns = { 'name' : fields.char('Holiday Status', size=64), } hr_holidays_status() class hr_holidays(osv.osv): _name = "hr.holidays" _description = "Holidays" _columns = { 'name' : fields.char('Description', size=64), 'date_from' : fields.datetime('Vacation start day'), 'date_to' : fields.datetime('Vacation end day'), 'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status"), 'employee_id' : fields.many2one('hr.employee', 'Employee', required=True), } _defaults = { 'employee_id' : _employee_get } _order = 'date_from desc' hr_holidays() class hr_expense_type(osv.osv): _name = "hr.expense.type" _description = "Expense type" _columns = { 'name' : fields.char('Type', size=128), } hr_expense_type() class hr_expense(osv.osv): _name = "hr.expense" _description = "Expense" _columns = { 'name' : fields.char('Short Description', size=128), 'date' : fields.date('Date'), 'amount' : fields.float('Amount'), 'txt' : fields.text('Long Description'), 'type' : fields.many2one('hr.expense.type', 'Expense type'), 'employee_id' : fields.many2one('hr.employee', 'Employee', required=True), 'state' : fields.selection([('draft', 'Draft'), ('confirm', 'Waiting confirmation'), ('accepted', 'Accepted'), ('refused', 'Refused')], 'State', readonly=True), } _defaults = { 'date' : lambda *a: time.strftime('%Y-%m-%d'), 'state': lambda *a: 'draft', 'employee_id' : _employee_get } hr_expense() # vim:tw=0:noexpandtab