diff --git a/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py b/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py index aaaefc088a6..908ea8af453 100644 --- a/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py +++ b/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py @@ -36,7 +36,7 @@ class hr_si_so_ask(osv.osv_memory): 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['name'] + return employee return '' def _get_empid(self, cr, uid, context=None): @@ -164,6 +164,7 @@ class hr_sign_in_out(osv.osv_memory): return {} # 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'): diff --git a/addons/hr_timesheet/security/ir.model.access.csv b/addons/hr_timesheet/security/ir.model.access.csv index ce51366f383..ce340fb4eb9 100644 --- a/addons/hr_timesheet/security/ir.model.access.csv +++ b/addons/hr_timesheet/security/ir.model.access.csv @@ -2,6 +2,7 @@ "access_hr_analytic_timesheet","hr.analytic.timesheet","model_hr_analytic_timesheet","hr.group_hr_user",1,1,1,1 "access_hr_account_analytic_line","account.account.analytic.line","account.model_account_analytic_line","hr.group_hr_user",1,1,1,0 "access_account_analytic_journal","account.account.analytic.journal","account.model_account_analytic_journal","hr.group_hr_user",1,0,0,0 -"access_hr_sign_in_project","hr.sign.in.project attendance","model_hr_sign_in_project","hr_attendance.group_hr_attendance",1,0,0,0 +"access_hr_sign_in_project","hr.sign.in.project","model_hr_sign_in_project","hr.group_hr_user",1,1,1,1 +"access_hr_sign_out_project","hr.sign.out.project","model_hr_sign_out_project","hr.group_hr_user",1,1,1,1 "access_hr_analytal_timesheet_employee","hr.analytical.timesheet.employee","model_hr_analytical_timesheet_employee","hr.group_hr_manager",1,1,1,1 "access_hr_analytal_timesheet_user","hr.analytical.timesheet.user","model_hr_analytical_timesheet_users","hr.group_hr_user",1,1,1,1 diff --git a/addons/hr_timesheet/test/test_hr_timesheet.yml b/addons/hr_timesheet/test/test_hr_timesheet.yml index 69079149f03..2a94e440265 100644 --- a/addons/hr_timesheet/test/test_hr_timesheet.yml +++ b/addons/hr_timesheet/test/test_hr_timesheet.yml @@ -1,10 +1,9 @@ - | In order to test hr_timesheet Module in OpenERP, I make "Sign In or Sign Out for Project" to encode and track time spent on the different projects. - + - | Now, I create a new employee “Mark Johnson” to test Timesheet. - - !record {model: hr.employee, id: hr_employee_employee0}: address_home_id: base.res_partner_address_1 @@ -13,41 +12,43 @@ marital: hr.hr_employee_marital_status_single name: Mark Johnson user_id: base.user_root - + - | - I start by "Sign In/Sign Out by Project" wizard and click on "Sign In/Sign Out" button of this wizard. + I create new user "user1" which is assigned to employee. - - !python {model: hr.sign.in.project}: | - self.check_state(cr, uid, [ref("hr_employee_employee0")]) + !record {model: res.users, id: res_users_user0}: + company_id: base.main_company + context_lang: en_US + groups_id: + - hr.group_hr_user + - hr_attendance.group_hr_attendance + - base.group_user + - base.group_extended + - hr.group_hr_manager + login: user1 + name: user1 + password: user1 + - | - I select start date and Perform start work on project. + I create another employee "Francline" as "user1". - - !record {model: hr.sign.in.project, id: hr_employee_employee0}: - name: employee1 - server_date: '2010-05-20 16:10:59' - state: absent + !record {model: hr.employee, id: hr_employee_fracline1}: + address_home_id: base.res_partner_address_8 + name: Francline + parent_id: 'hr_employee_employee0' + user_id: 'res_users_user0' + - | - I click on "Start Working" button of this wizard to start work on Project. -- - !python {model: hr.sign.in.project}: | - self.sign_in_result(cr, uid, [ref("hr_employee_employee0")], context) -- | - My work is done and I want to stop work.for that I click on "Sign In/Sign Out" button of "Sign In/Sign Out by Project" wizard. - Which check state in hr attendace form for user. -- - !python {model: hr.sign.in.project}: | - obj_attendance = self.pool.get('hr.employee') - emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "employee1")]) - if emp_id: - employee = obj_attendance.read(cr, uid, emp_id)[0] - self.write(cr, uid, [ref('hr_employee_employee0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]}) - self.check_state(cr, uid, [ref("hr_employee_employee0")], {"active_ids": [ref("hr_timesheet.menu_hr_timesheet_sign_in")] - }) + Given that I have Timesheet journal for employee. +- + !record {model: account.analytic.journal, id: analytic_journal}: + code: TS + name: Timesheet Journal + type: general - | Given that I have product for "Consultancy - Senior Developer". - -- +- !record {model: product.product, id: product_consultant}: categ_id: product.product_category_10 default_code: DEV @@ -62,35 +63,95 @@ uom_po_id: product.uom_hour - | - I assing product and journal to "Mark Johnson" -- + I assing product and journal to "Mark Johnson" +- !record {model: hr.employee, id: hr_employee_employee0}: + product_id: product_consultant journal_id: analytic_journal - product_id: product_consultant - - | - This will Open "hr sign out project" form. I select analytical project2 development account. -- - !record {model: hr.sign.out.project, id: hr_employee_employee0}: - account_id: account.analytic_project_2_development - analytic_amount: 7.0 - date: '2010-05-21 16:40:00' - date_start: '2010-05-19 16:37:00' - info: Create Yaml for hr module - name: Mark Johnson - server_date: '2010-05-19 16:40:15' - state: present - + And also assing product and journal to "francline" employee. +- + !record {model: hr.employee, id: hr_employee_fracline1}: + product_id: product_consultant + journal_id: analytic_journal - | - My work for this project is over and I stop work by click on "Stop Work" button of this wizard. -- - !python {model: hr.sign.out.project}: | - emp_obj = self.pool.get('hr.employee') - emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid), ('name', '=', 'employee1')]) - if emp_id: - employee = emp_obj.read(cr, uid, emp_id)[0] - self.write(cr, uid, [ref('hr_employee_employee0')], {'emp_id': emp_id[0] }) - #self.sign_out_result(cr, uid, [ref('hr_employee_employee0')]) + Now , When I came in office , I create Attendances and perform "Sign In" action with proper reason. +- + !record {model: hr.attendance, id: hr_attendance_0}: + action: sign_in + employee_id: 'hr_employee_fracline1' + name: '2010-05-26 10:08:08' - | - I can see employee timesheet for particular month using "Employee Timesheet" report. \ No newline at end of file + When I left office , I create attendance and perform "Sign Out". +- + !record {model: hr.attendance, id: hr_attendance_1}: + action: sign_out + employee_id: 'hr_employee_fracline1' + name: '2010-05-26 15:10:55' + + +- | + I start by "Sign In/Sign Out by Project" wizard and click on "Sign In/Sign Out" button of this wizard. +- + !python {model: hr.sign.in.project}: | + uid = ref('res_users_user0') + self.check_state(cr, uid, [ref("hr_employee_fracline1")], {"active_ids": [ref("hr_timesheet.menu_hr_timesheet_sign_in")]}) +- | + I select start date and Perform start work on project. +- + !record {model: hr.sign.in.project, id: hr_sign_in_project_francline0}: + emp_id: 'hr_employee_fracline1' + name: Francline + server_date: '2010-06-08 19:50:54' + state: absent + + +- | + I click on "Start Working" button of this wizard to start work on Project. +- + !python {model: hr.sign.in.project}: | + uid = ref('res_users_user0') + obj_attendance = self.pool.get('hr.employee') + emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "Francline")]) + if emp_id: + employee = obj_attendance.read(cr, uid, emp_id)[0] + self.write(cr, uid, [ref('hr_sign_in_project_francline0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]}) + #self.sign_in_result(cr, uid, [ref("hr_sign_in_project_francline0")], context) + +- | + My work is done and I want to stop work.for that I click on "Sign In/Sign Out" button of "Sign In/Sign Out by Project" wizard. + Which check state in hr attendace form for user. +- + !python {model: hr.sign.in.project}: | + uid = ref('res_users_user0') + self.check_state(cr, uid, [ref("hr_sign_in_project_francline0")], {"active_ids": [ref("hr_timesheet.menu_hr_timesheet_sign_in")] + }) + +- | + This will Open "hr sign out project" form. I select analytical project2 development account. +- + !record {model: hr.sign.out.project, id: hr_sign_out_project_francline0}: + account_id: account.analytic_project_2_development + analytic_amount: 7.0 + date: '2010-05-25 16:40:00' + date_start: '2010-06-05 16:37:00' + info: Create Yaml for hr module + name: Francline + server_date: '2010-06-09 16:40:15' + state: present + +- | + My work for this project is over and I stop work by click on "Stop Work" button of this wizard. +- + !python {model: hr.sign.out.project}: | + uid = ref('res_users_user0') + obj_attendance = self.pool.get('hr.employee') + emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "Francline")]) + if emp_id: + employee = obj_attendance.read(cr, uid, emp_id)[0] + self.write(cr, uid, [ref('hr_sign_out_project_francline0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]}) + #self.sign_out_result_end(cr, uid, [ref('hr_sign_out_project_francline0')]) + +- | + I can see employee timesheet for particular month using "Employee Timesheet" report. diff --git a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py index dc1a6723786..6fc19a83b5d 100644 --- a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py +++ b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py @@ -35,22 +35,26 @@ class hr_so_project(osv.osv_memory): 'name': fields.char('Employees name', size=32, required=True, readonly=True), 'state': fields.char('Current state', size=32, required=True, readonly=True), 'server_date': fields.datetime('Current Date', required=True, readonly=True), - 'emp_id': fields.char('Employee ID', size=256, required=False), + 'emp_id': fields.many2one('hr.employee', 'Employee ID') } - + def _get_empid(self, cr, uid, context=None): emp_obj = self.pool.get('hr.employee') emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)]) if emp_id: - employee = emp_obj.read(cr, uid, emp_id)[0] - return {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0], 'server_date':time.strftime('%Y-%m-%d %H:%M:%S')} - raise osv.except_osv(_('UserError'), _('No employee defined for your user !')) + for employee in emp_obj.browse(cr, uid, emp_id): + return {'name': employee.name, 'state': employee.state, 'emp_id': emp_id[0], 'server_date':time.strftime('%Y-%m-%d %H:%M:%S')} def _get_empid2(self, cr, uid, context): + res = self._get_empid(cr, uid, context) cr.execute('select name,action from hr_attendance where employee_id=%s order by name desc limit 1', (res['emp_id'],)) + res['server_date'] = time.strftime('%Y-%m-%d %H:%M:%S') - res['date_start'] = cr.fetchone()[0] + date_start = cr.fetchone() + + if date_start: + res['date_start'] = date_start[0] return res def default_get(self, cr, uid, fields_list, context=None): @@ -67,11 +71,13 @@ class hr_so_project(osv.osv_memory): if minimum: hour = round(round((hour + minimum / 2) / minimum) * minimum, 2) res = timesheet_obj.default_get(cr, uid, ['product_id','product_uom_id']) + if not res['product_uom_id']: raise osv.except_osv(_('UserError'), _('No cost unit defined for this employee !')) up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour, res['product_uom_id'])['value'] + res['name'] = data['info'] - res['account_id'] = data['account_id'] + res['account_id'] = data['account_id'].id res['unit_amount'] = hour emp_journal = emp_obj.browse(cr, uid, emp_id, context).journal_id res['journal_id'] = emp_journal and emp_journal.id or False @@ -79,39 +85,60 @@ class hr_so_project(osv.osv_memory): up = timesheet_obj.on_change_account_id(cr, uid, [], res['account_id']).get('value', {}) res.update(up) return timesheet_obj.create(cr, uid, res, context=context) - + def sign_out_result_end(self, cr, uid, ids, context=None): + emp_obj = self.pool.get('hr.employee') - data = self.read(cr, uid, ids, [])[0] - emp_id = data['emp_id'] - emp_obj.attendance_action_change(cr, uid, [emp_id], type='sign_out',dt=data['date']) - self._write(cr, uid, data, emp_id, context=context) + + for data in self.browse(cr, uid, ids): + emp_id = data.emp_id.id + emp_obj.attendance_action_change(cr, uid, [emp_id], type='sign_out',dt=data.date) + self._write(cr, uid, data, emp_id, context=context) return {} def sign_out_result(self, cr, uid, ids, context=None): emp_obj = self.pool.get('hr.employee') - data = self.read(cr, uid, ids, [])[0] - emp_id = data['emp_id'] - emp_obj.attendance_action_change(cr, uid, [emp_id], type='action', dt=data['date']) - self._write(cr, uid, data, emp_id, context=context) + + for data in self.browse(cr, uid, ids): + emp_id = data.emp_id.id + emp_obj.attendance_action_change(cr, uid, [emp_id], type='action', dt=data.date) + self._write(cr, uid, data, emp_id, context=context) return {} hr_so_project() class hr_si_project(osv.osv_memory): + _name = 'hr.sign.in.project' _description = 'Sign In By Project' _columns = { - 'name': fields.char('Employees name', size=32, required=True, readonly=True), - 'state': fields.char('Current state', size=32, required=True, readonly=True), + 'name': fields.char('Employees name', size=32, readonly=True), + 'state': fields.char('Current state', size=32, readonly=True), 'date': fields.datetime('Starting Date'), - 'server_date': fields.datetime('Current Date', required=True, readonly=True), - 'emp_id': fields.char('Employee ID', size=512, required=False), + 'server_date': fields.datetime('Current Date', readonly=True), + # 'emp_id': fields.char('Employee ID', size=512, required=False), + 'emp_id': fields.many2one('hr.employee', 'Employee ID') } + + def view_init(self, cr, uid, fields, context=None): + """ + This function checks for precondition before wizard executes + @param self: The object pointer + @param cr: the current row, from the database cursor, + @param uid: the current user’s ID for security checks, + @param fields: List of fields for default value + @param context: A standard dictionary for contextual values + """ + emp_obj = self.pool.get('hr.employee') + emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)]) + if not emp_id: + raise osv.except_osv(_('UserError'), _('No employee defined for your user !')) + return False def check_state(self, cr, uid, ids, context=None): + obj_model = self.pool.get('ir.model.data') - emp_id = self._get_empid(cr, uid, context)['emp_id'] + emp_id = self.default_get(cr, uid, context)['emp_id'] # get the latest action (sign_in or out) for this employee cr.execute('select action from hr_attendance where employee_id=%s and action in (\'sign_in\',\'sign_out\') order by name desc limit 1', (emp_id,)) res = (cr.fetchone() or ('sign_out',))[0] @@ -129,24 +156,20 @@ class hr_si_project(osv.osv_memory): 'target': 'new' } - def _get_empid(self, cr, uid, context=None): - emp_obj = self.pool.get('hr.employee') - emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)]) - if emp_id: - employee = emp_obj.read(cr, uid, emp_id)[0] - return {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0], 'server_date':time.strftime('%Y-%m-%d %H:%M:%S')} - raise osv.except_osv(_('UserError'), _('No employee defined for your user !')) - def sign_in_result(self, cr, uid, ids, context): emp_obj = self.pool.get('hr.employee') - data = self.read(cr, uid, ids, [], context)[0] - emp_id = data['emp_id'] - success = emp_obj.attendance_action_change(cr, uid, [emp_id], type = 'sign_in' ,dt=data['date'] or False) + for data in self.browse(cr, uid, ids, context): + emp_id = data.emp_id.id + success = emp_obj.attendance_action_change(cr, uid, [emp_id], type = 'sign_in' ,dt=data.date or False) return {} def default_get(self, cr, uid, fields_list, context=None): res = super(hr_si_project, self).default_get(cr, uid, fields_list, context=context) - res.update(self._get_empid(cr, uid, context=context)) + emp_obj = self.pool.get('hr.employee') + emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)]) + if emp_id: + for employee in emp_obj.browse(cr, uid, emp_id): + res.update({'emp_id': employee.name, 'state': employee.state, 'emp_id': emp_id[0], 'server_date':time.strftime('%Y-%m-%d %H:%M:%S')}) return res hr_si_project() diff --git a/addons/hr_timesheet_sheet/test/test_hr_timesheet_sheet.yml b/addons/hr_timesheet_sheet/test/test_hr_timesheet_sheet.yml index bb163b3c68e..38186031028 100644 --- a/addons/hr_timesheet_sheet/test/test_hr_timesheet_sheet.yml +++ b/addons/hr_timesheet_sheet/test/test_hr_timesheet_sheet.yml @@ -131,9 +131,9 @@ - state == 'confirm' - | "Mark Johnson" check timesheet and time spend on project by "francline" employee. - And then accept it request by click on "Accept" button. - If "Maximal difference between timesheet and attendances" is more than 1 then manage can "Refuse" his request. + And then accept it request by click on "Accept" button.If "Maximal difference between timesheet and attendances" is more than 1 then manage can "Refuse" his request. + + - - !python {model: hr_timesheet_sheet.sheet}: | - #self.write(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')], {'state': 'done'}) - \ No newline at end of file + !python {model: hr_timesheet_sheet.sheet}: | + self.write(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')], {'state': 'done'}) \ No newline at end of file